diff --git a/DEPS b/DEPS
index bae979d..1410e55 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '473466c017bd74da21c2165990f8b33a98c6b409',
+  'skia_revision': '93f66bc3af522fdd2a5315407ba6d3f65c13fd1c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '515eaeb066dee53befafedd9f228b5ffc1e0c0e2',
+  'v8_revision': 'b39aa98a76d81e56a904292df9a7e0c06efb0a9c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -55,7 +55,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
-  'buildtools_revision': '4dcb5ed1079e7a527061925637b8cc627e289e82',
+  'buildtools_revision': '56eaae134648135663c4aa1ed82278572b5f35ef',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -91,7 +91,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '2c7c14263b4e48f3899aefff47b8c8acb2d35dee',
+  'catapult_revision': '9d7d3a63f4429b0d0ad80065e2b09476fe3b9738',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
diff --git a/android_webview/java/src/org/chromium/android_webview/AndroidProtocolHandler.java b/android_webview/java/src/org/chromium/android_webview/AndroidProtocolHandler.java
index 3db25bb..20717b6 100644
--- a/android_webview/java/src/org/chromium/android_webview/AndroidProtocolHandler.java
+++ b/android_webview/java/src/org/chromium/android_webview/AndroidProtocolHandler.java
@@ -60,11 +60,42 @@
         return null;
     }
 
+    // Assumes input string is in the format "foo.bar.baz" and strips out the last component.
+    // Returns null on failure.
+    private static String removeOneSuffix(String input) {
+        if (input == null) return null;
+        int lastDotIndex = input.lastIndexOf('.');
+        if (lastDotIndex == -1) return null;
+        return input.substring(0, lastDotIndex);
+    }
+
+    private static Class<?> getClazz(Context context, String packageName, String assetType)
+            throws ClassNotFoundException {
+        return context.getClassLoader().loadClass(packageName + ".R$" + assetType);
+    }
+
     private static int getFieldId(Context context, String assetType, String assetName)
         throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
-        Class<?> d = context.getClassLoader()
-                .loadClass(context.getPackageName() + ".R$" + assetType);
-        java.lang.reflect.Field field = d.getField(assetName);
+        Class<?> clazz = null;
+        try {
+            clazz = getClazz(context, context.getPackageName(), assetType);
+        } catch (ClassNotFoundException e) {
+            // Strip out components from the end so gradle generated application suffix such as
+            // com.example.my.pkg.pro works. This is by no means bulletproof.
+            String packageName = context.getPackageName();
+            while (clazz == null) {
+                packageName = removeOneSuffix(packageName);
+                // Throw original exception which contains the entire package id.
+                if (packageName == null) throw e;
+                try {
+                    clazz = getClazz(context, packageName, assetType);
+                } catch (ClassNotFoundException ignored) {
+                    // Strip and try again.
+                }
+            }
+        }
+
+        java.lang.reflect.Field field = clazz.getField(assetName);
         int id = field.getInt(null);
         return id;
     }
diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc
index ce1d576..47bc22d 100644
--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -121,15 +121,11 @@
     // Browser process (no type specified).
 
     base::android::RegisterApkAssetWithGlobalDescriptors(
-        kV8NativesDataDescriptor32,
-        gin::V8Initializer::GetNativesFilePath(true).AsUTF8Unsafe());
+        kV8NativesDataDescriptor,
+        gin::V8Initializer::GetNativesFilePath().AsUTF8Unsafe());
     base::android::RegisterApkAssetWithGlobalDescriptors(
         kV8SnapshotDataDescriptor32,
         gin::V8Initializer::GetSnapshotFilePath(true).AsUTF8Unsafe());
-
-    base::android::RegisterApkAssetWithGlobalDescriptors(
-        kV8NativesDataDescriptor64,
-        gin::V8Initializer::GetNativesFilePath(false).AsUTF8Unsafe());
     base::android::RegisterApkAssetWithGlobalDescriptors(
         kV8SnapshotDataDescriptor64,
         gin::V8Initializer::GetSnapshotFilePath(false).AsUTF8Unsafe());
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 516246a..9d2bc69 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -66,6 +66,9 @@
       'common/default_accessibility_delegate.h',
       'common/focus_cycler.cc',
       'common/focus_cycler.h',
+      'common/keyboard/keyboard_ui.cc',
+      'common/keyboard/keyboard_ui.h',
+      'common/keyboard/keyboard_ui_observer.h',
       'common/login_status.h',
       'common/material_design/material_design_controller.cc',
       'common/material_design/material_design_controller.h',
@@ -148,6 +151,8 @@
       'common/system/tray/tray_bar_button_with_title.h',
       'common/system/tray/tray_constants.cc',
       'common/system/tray/tray_constants.h',
+      'common/system/tray/tray_details_view.cc',
+      'common/system/tray/tray_details_view.h',
       'common/system/tray/tray_empty.cc',
       'common/system/tray/tray_empty.h',
       'common/system/tray/tray_image_item.cc',
@@ -171,6 +176,8 @@
       'common/system/tray/view_click_listener.h',
       'common/system/tray/wm_system_tray_notifier.cc',
       'common/system/tray/wm_system_tray_notifier.h',
+      'common/system/tray_accessibility.cc',
+      'common/system/tray_accessibility.h',
       'common/system/update/tray_update.cc',
       'common/system/update/tray_update.h',
       'common/system/update/update_observer.h',
@@ -383,9 +390,6 @@
       'host/transformer_helper.h',
       'ime/input_method_event_handler.cc',
       'ime/input_method_event_handler.h',
-      'keyboard/keyboard_ui.cc',
-      'keyboard/keyboard_ui.h',
-      'keyboard/keyboard_ui_observer.h',
       'keyboard_uma_event_filter.cc',
       'keyboard_uma_event_filter.h',
       'link_handler_model.cc',
@@ -600,12 +604,8 @@
       'system/tray/tray_background_view.h',
       'system/tray/tray_bubble_wrapper.cc',
       'system/tray/tray_bubble_wrapper.h',
-      'system/tray/tray_details_view.cc',
-      'system/tray/tray_details_view.h',
       'system/tray/tray_event_filter.cc',
       'system/tray/tray_event_filter.h',
-      'system/tray_accessibility.cc',
-      'system/tray_accessibility.h',
       'system/user/button_from_view.cc',
       'system/user/button_from_view.h',
       'system/user/login_status.cc',
@@ -903,6 +903,7 @@
       'common/system/chromeos/power/power_status_view_unittest.cc',
       'common/system/chromeos/power/tray_power_unittest.cc',
       'common/system/date/date_view_unittest.cc',
+      'common/system/tray/tray_details_view_unittest.cc',
       'common/system/update/tray_update_unittest.cc',
       'content/display/screen_orientation_controller_chromeos_unittest.cc',
       'content/keyboard_overlay/keyboard_overlay_delegate_unittest.cc',
@@ -972,7 +973,6 @@
       'system/toast/toast_manager_unittest.cc',
       'system/tray/media_security/multi_profile_media_tray_item_unittest.cc',
       'system/tray/system_tray_unittest.cc',
-      'system/tray/tray_details_view_unittest.cc',
       'system/user/tray_user_unittest.cc',
       'system/web_notification/ash_popup_alignment_delegate_unittest.cc',
       'system/web_notification/web_notification_tray_unittest.cc',
diff --git a/ash/keyboard/keyboard_ui.cc b/ash/common/keyboard/keyboard_ui.cc
similarity index 92%
rename from ash/keyboard/keyboard_ui.cc
rename to ash/common/keyboard/keyboard_ui.cc
index 1ab3f10..4573da4 100644
--- a/ash/keyboard/keyboard_ui.cc
+++ b/ash/common/keyboard/keyboard_ui.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/keyboard/keyboard_ui.h"
+#include "ash/common/keyboard/keyboard_ui.h"
 
 #include "ash/common/accessibility_delegate.h"
+#include "ash/common/keyboard/keyboard_ui_observer.h"
 #include "ash/common/system/accessibility_observer.h"
 #include "ash/common/system/tray/wm_system_tray_notifier.h"
+#include "ash/common/system/tray_accessibility.h"
 #include "ash/common/wm_shell.h"
-#include "ash/keyboard/keyboard_ui_observer.h"
-#include "ash/system/tray_accessibility.h"
 #include "base/memory/ptr_util.h"
 #include "ui/keyboard/keyboard_controller.h"
 
diff --git a/ash/keyboard/keyboard_ui.h b/ash/common/keyboard/keyboard_ui.h
similarity index 89%
rename from ash/keyboard/keyboard_ui.h
rename to ash/common/keyboard/keyboard_ui.h
index 71a28cb..82a2c64 100644
--- a/ash/keyboard/keyboard_ui.h
+++ b/ash/common/keyboard/keyboard_ui.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_KEYBOARD_KEYBOARD_UI_H_
-#define ASH_KEYBOARD_KEYBOARD_UI_H_
+#ifndef ASH_COMMON_KEYBOARD_KEYBOARD_UI_H_
+#define ASH_COMMON_KEYBOARD_KEYBOARD_UI_H_
 
 #include <memory>
 
@@ -46,4 +46,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_KEYBOARD_KEYBOARD_UI_H_
+#endif  // ASH_COMMON_KEYBOARD_KEYBOARD_UI_H_
diff --git a/ash/keyboard/keyboard_ui_observer.h b/ash/common/keyboard/keyboard_ui_observer.h
similarity index 72%
rename from ash/keyboard/keyboard_ui_observer.h
rename to ash/common/keyboard/keyboard_ui_observer.h
index c1b130b..b3147c9 100644
--- a/ash/keyboard/keyboard_ui_observer.h
+++ b/ash/common/keyboard/keyboard_ui_observer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_KEYBOARD_KEYBOARD_UI_OBSERVER_H_
-#define ASH_KEYBOARD_KEYBOARD_UI_OBSERVER_H_
+#ifndef ASH_COMMON_KEYBOARD_KEYBOARD_UI_OBSERVER_H_
+#define ASH_COMMON_KEYBOARD_KEYBOARD_UI_OBSERVER_H_
 
 #include "ash/ash_export.h"
 #include "base/macros.h"
@@ -20,4 +20,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_KEYBOARD_KEYBOARD_UI_OBSERVER_H_
+#endif  // ASH_COMMON_KEYBOARD_KEYBOARD_UI_OBSERVER_H_
diff --git a/ash/system/tray/tray_details_view.cc b/ash/common/system/tray/tray_details_view.cc
similarity index 98%
rename from ash/system/tray/tray_details_view.cc
rename to ash/common/system/tray/tray_details_view.cc
index c0cf3bf..5ac0443 100644
--- a/ash/system/tray/tray_details_view.cc
+++ b/ash/common/system/tray/tray_details_view.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/tray/tray_details_view.h"
+#include "ash/common/system/tray/tray_details_view.h"
 
 #include "ash/common/system/tray/fixed_sized_scroll_view.h"
 #include "ash/common/system/tray/system_tray_item.h"
diff --git a/ash/system/tray/tray_details_view.h b/ash/common/system/tray/tray_details_view.h
similarity index 92%
rename from ash/system/tray/tray_details_view.h
rename to ash/common/system/tray/tray_details_view.h
index 63e118b..1cf8eaa 100644
--- a/ash/system/tray/tray_details_view.h
+++ b/ash/common/system/tray/tray_details_view.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SYSTEM_TRAY_TRAY_DETAILS_VIEW_H_
-#define ASH_SYSTEM_TRAY_TRAY_DETAILS_VIEW_H_
+#ifndef ASH_COMMON_SYSTEM_TRAY_TRAY_DETAILS_VIEW_H_
+#define ASH_COMMON_SYSTEM_TRAY_TRAY_DETAILS_VIEW_H_
 
 #include "ash/ash_export.h"
 #include "ash/common/system/tray/special_popup_row.h"
@@ -66,4 +66,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_SYSTEM_TRAY_TRAY_DETAILS_VIEW_H_
+#endif  // ASH_COMMON_SYSTEM_TRAY_TRAY_DETAILS_VIEW_H_
diff --git a/ash/system/tray/tray_details_view_unittest.cc b/ash/common/system/tray/tray_details_view_unittest.cc
similarity index 99%
rename from ash/system/tray/tray_details_view_unittest.cc
rename to ash/common/system/tray/tray_details_view_unittest.cc
index 4f4e4626c..bc7611e8 100644
--- a/ash/system/tray/tray_details_view_unittest.cc
+++ b/ash/common/system/tray/tray_details_view_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/tray/tray_details_view.h"
+#include "ash/common/system/tray/tray_details_view.h"
 
 #include "ash/common/system/tray/hover_highlight_view.h"
 #include "ash/common/system/tray/special_popup_row.h"
diff --git a/ash/system/tray_accessibility.cc b/ash/common/system/tray_accessibility.cc
similarity index 99%
rename from ash/system/tray_accessibility.cc
rename to ash/common/system/tray_accessibility.cc
index a1c220f7..e6c05a94 100644
--- a/ash/system/tray_accessibility.cc
+++ b/ash/common/system/tray_accessibility.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/system/tray_accessibility.h"
+#include "ash/common/system/tray_accessibility.h"
 
 #include "ash/common/accessibility_delegate.h"
 #include "ash/common/accessibility_types.h"
@@ -10,12 +10,12 @@
 #include "ash/common/system/tray/hover_highlight_view.h"
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_item_more.h"
 #include "ash/common/system/tray/tray_popup_label_button.h"
 #include "ash/common/system/tray/wm_system_tray_notifier.h"
 #include "ash/common/wm_shell.h"
 #include "ash/system/tray/system_tray.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "base/strings/utf_string_conversions.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
diff --git a/ash/system/tray_accessibility.h b/ash/common/system/tray_accessibility.h
similarity index 95%
rename from ash/system/tray_accessibility.h
rename to ash/common/system/tray_accessibility.h
index e400711..05cd5e5 100644
--- a/ash/system/tray_accessibility.h
+++ b/ash/common/system/tray_accessibility.h
@@ -2,18 +2,18 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef ASH_SYSTEM_TRAY_ACCESSIBILITY_H_
-#define ASH_SYSTEM_TRAY_ACCESSIBILITY_H_
+#ifndef ASH_COMMON_SYSTEM_TRAY_ACCESSIBILITY_H_
+#define ASH_COMMON_SYSTEM_TRAY_ACCESSIBILITY_H_
 
 #include <stdint.h>
 
 #include "ash/common/accessibility_delegate.h"
 #include "ash/common/shell_observer.h"
 #include "ash/common/system/accessibility_observer.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_image_item.h"
 #include "ash/common/system/tray/tray_notification_view.h"
 #include "ash/common/system/tray/view_click_listener.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "base/macros.h"
 #include "ui/gfx/font.h"
 #include "ui/views/controls/button/button.h"
@@ -140,4 +140,4 @@
 
 }  // namespace ash
 
-#endif  // ASH_SYSTEM_TRAY_ACCESSIBILITY_H_
+#endif  // ASH_COMMON_SYSTEM_TRAY_ACCESSIBILITY_H_
diff --git a/ash/shell.cc b/ash/shell.cc
index 0869acb1..2ee91955 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -16,6 +16,7 @@
 #include "ash/autoclick/autoclick_controller.h"
 #include "ash/common/accessibility_delegate.h"
 #include "ash/common/ash_switches.h"
+#include "ash/common/keyboard/keyboard_ui.h"
 #include "ash/common/session/session_state_delegate.h"
 #include "ash/common/shelf/shelf_item_delegate.h"
 #include "ash/common/shelf/shelf_item_delegate_manager.h"
@@ -45,7 +46,6 @@
 #include "ash/high_contrast/high_contrast_controller.h"
 #include "ash/host/ash_window_tree_host_init_params.h"
 #include "ash/ime/input_method_event_handler.h"
-#include "ash/keyboard/keyboard_ui.h"
 #include "ash/keyboard_uma_event_filter.h"
 #include "ash/magnifier/magnification_controller.h"
 #include "ash/magnifier/partial_magnification_controller.h"
diff --git a/ash/system/cast/tray_cast.cc b/ash/system/cast/tray_cast.cc
index c8bf768..cbb97e4 100644
--- a/ash/system/cast/tray_cast.cc
+++ b/ash/system/cast/tray_cast.cc
@@ -13,6 +13,7 @@
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/throbber_view.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_item_more.h"
 #include "ash/common/system/tray/tray_item_view.h"
 #include "ash/common/system/tray/tray_popup_label_button.h"
@@ -23,7 +24,6 @@
 #include "ash/system/chromeos/screen_security/screen_tray_item.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "base/bind.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
diff --git a/ash/system/chromeos/audio/audio_detailed_view.h b/ash/system/chromeos/audio/audio_detailed_view.h
index e36d7f6..e6d930e 100644
--- a/ash/system/chromeos/audio/audio_detailed_view.h
+++ b/ash/system/chromeos/audio/audio_detailed_view.h
@@ -5,8 +5,8 @@
 #ifndef ASH_SYSTEM_CHROMEOS_AUDIO_AUDIO_DETAILED_VIEW_H_
 #define ASH_SYSTEM_CHROMEOS_AUDIO_AUDIO_DETAILED_VIEW_H_
 
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/view_click_listener.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "base/macros.h"
 #include "chromeos/audio/audio_device.h"
 #include "ui/gfx/font.h"
diff --git a/ash/system/chromeos/bluetooth/tray_bluetooth.cc b/ash/system/chromeos/bluetooth/tray_bluetooth.cc
index 4345718a..dbb429b 100644
--- a/ash/system/chromeos/bluetooth/tray_bluetooth.cc
+++ b/ash/system/chromeos/bluetooth/tray_bluetooth.cc
@@ -10,6 +10,7 @@
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/throbber_view.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_item_more.h"
 #include "ash/common/system/tray/tray_popup_header_button.h"
 #include "ash/common/system/tray/view_click_listener.h"
@@ -17,7 +18,6 @@
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "grit/ash_resources.h"
 #include "grit/ash_strings.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/ash/system/chromeos/network/network_detailed_view.h b/ash/system/chromeos/network/network_detailed_view.h
index 12d0be1..1b1b2fe 100644
--- a/ash/system/chromeos/network/network_detailed_view.h
+++ b/ash/system/chromeos/network/network_detailed_view.h
@@ -5,7 +5,7 @@
 #ifndef ASH_SYSTEM_CHROMEOS_NETWORK_NETWORK_DETAILED_VIEW_H
 #define ASH_SYSTEM_CHROMEOS_NETWORK_NETWORK_DETAILED_VIEW_H
 
-#include "ash/system/tray/tray_details_view.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "chromeos/network/network_state_handler.h"
 
 namespace ash {
diff --git a/ash/system/chromeos/network/network_state_list_detailed_view.cc b/ash/system/chromeos/network/network_state_list_detailed_view.cc
index 53050b4..80a559f6 100644
--- a/ash/system/chromeos/network/network_state_list_detailed_view.cc
+++ b/ash/system/chromeos/network/network_state_list_detailed_view.cc
@@ -17,6 +17,7 @@
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/throbber_view.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_popup_header_button.h"
 #include "ash/common/system/tray/tray_popup_label_button.h"
 #include "ash/common/wm_shell.h"
@@ -27,7 +28,6 @@
 #include "ash/system/chromeos/network/tray_network_state_observer.h"
 #include "ash/system/chromeos/network/vpn_list_view.h"
 #include "ash/system/tray/system_tray.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/ash/system/chromeos/network/tray_sms.cc b/ash/system/chromeos/network/tray_sms.cc
index 43f29d3..07035ef 100644
--- a/ash/system/chromeos/network/tray_sms.cc
+++ b/ash/system/chromeos/network/tray_sms.cc
@@ -6,6 +6,7 @@
 
 #include "ash/common/system/tray/fixed_sized_scroll_view.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_item_more.h"
 #include "ash/common/system/tray/tray_item_view.h"
 #include "ash/common/system/tray/tray_notification_view.h"
@@ -14,7 +15,6 @@
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_bubble.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chromeos/network/network_event_log.h"
diff --git a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
index 2b8dfbf..5d56f12 100644
--- a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
+++ b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.cc
@@ -4,12 +4,12 @@
 
 #include "ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.h"
 
+#include "ash/common/keyboard/keyboard_ui.h"
 #include "ash/common/material_design/material_design_controller.h"
 #include "ash/common/shelf/shelf_constants.h"
 #include "ash/common/shelf/wm_shelf_util.h"
 #include "ash/common/system/tray/tray_constants.h"
 #include "ash/common/system/tray/tray_utils.h"
-#include "ash/keyboard/keyboard_ui.h"
 #include "ash/shelf/shelf.h"
 #include "ash/shelf/shelf_util.h"
 #include "ash/shell.h"
diff --git a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.h b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.h
index 2b16b73..a7cca7fe 100644
--- a/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.h
+++ b/ash/system/chromeos/virtual_keyboard/virtual_keyboard_tray.h
@@ -5,7 +5,7 @@
 #ifndef ASH_SYSTEM_CHROMEOS_VIRTUAL_KEYBOARD_VIRTUAL_KEYBOARD_TRAY_H_
 #define ASH_SYSTEM_CHROMEOS_VIRTUAL_KEYBOARD_VIRTUAL_KEYBOARD_TRAY_H_
 
-#include "ash/keyboard/keyboard_ui_observer.h"
+#include "ash/common/keyboard/keyboard_ui_observer.h"
 #include "ash/system/tray/tray_background_view.h"
 #include "ash/system/user/login_status.h"
 #include "base/macros.h"
diff --git a/ash/system/ime/tray_ime_chromeos.cc b/ash/system/ime/tray_ime_chromeos.cc
index 873a38c..fb5ce403 100644
--- a/ash/system/ime/tray_ime_chromeos.cc
+++ b/ash/system/ime/tray_ime_chromeos.cc
@@ -10,18 +10,18 @@
 #include "ash/common/system/tray/hover_highlight_view.h"
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/tray_item_more.h"
 #include "ash/common/system/tray/tray_item_view.h"
 #include "ash/common/system/tray/tray_utils.h"
 #include "ash/common/system/tray/wm_system_tray_notifier.h"
+#include "ash/common/system/tray_accessibility.h"
 #include "ash/common/wm_shell.h"
 #include "ash/metrics/user_metrics_recorder.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray/tray_details_view.h"
-#include "ash/system/tray_accessibility.h"
 #include "ash/virtual_keyboard_controller.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
diff --git a/ash/system/ime/tray_ime_chromeos_unittest.cc b/ash/system/ime/tray_ime_chromeos_unittest.cc
index 1ff47462..1af23e7c 100644
--- a/ash/system/ime/tray_ime_chromeos_unittest.cc
+++ b/ash/system/ime/tray_ime_chromeos_unittest.cc
@@ -6,10 +6,10 @@
 
 #include "ash/common/accessibility_delegate.h"
 #include "ash/common/accessibility_types.h"
+#include "ash/common/system/tray/tray_details_view.h"
 #include "ash/common/system/tray/wm_system_tray_notifier.h"
 #include "ash/common/wm_shell.h"
 #include "ash/system/status_area_widget.h"
-#include "ash/system/tray/tray_details_view.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/status_area_widget_test_helper.h"
 #include "ash/test/virtual_keyboard_test_helper.h"
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc
index c7f95991..7340690 100644
--- a/ash/system/tray/system_tray.cc
+++ b/ash/system/tray/system_tray.cc
@@ -13,6 +13,7 @@
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/system_tray_item.h"
 #include "ash/common/system/tray/tray_constants.h"
+#include "ash/common/system/tray_accessibility.h"
 #include "ash/common/system/update/tray_update.h"
 #include "ash/common/wm_shell.h"
 #include "ash/metrics/user_metrics_recorder.h"
@@ -21,7 +22,6 @@
 #include "ash/system/cast/tray_cast.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/tray/tray_bubble_wrapper.h"
-#include "ash/system/tray_accessibility.h"
 #include "ash/system/user/login_status.h"
 #include "ash/system/user/tray_user.h"
 #include "ash/system/user/tray_user_separator.h"
diff --git a/ash/sysui/keyboard_ui_mus.cc b/ash/sysui/keyboard_ui_mus.cc
index 97e1cd8d..00f1864 100644
--- a/ash/sysui/keyboard_ui_mus.cc
+++ b/ash/sysui/keyboard_ui_mus.cc
@@ -4,7 +4,7 @@
 
 #include "ash/sysui/keyboard_ui_mus.h"
 
-#include "ash/keyboard/keyboard_ui_observer.h"
+#include "ash/common/keyboard/keyboard_ui_observer.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "base/memory/ptr_util.h"
diff --git a/ash/sysui/keyboard_ui_mus.h b/ash/sysui/keyboard_ui_mus.h
index 623c2ec..2ffee67 100644
--- a/ash/sysui/keyboard_ui_mus.h
+++ b/ash/sysui/keyboard_ui_mus.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 
-#include "ash/keyboard/keyboard_ui.h"
+#include "ash/common/keyboard/keyboard_ui.h"
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ui/keyboard/keyboard.mojom.h"
diff --git a/blimp/engine/app/blimp_engine_crash_keys.cc b/blimp/engine/app/blimp_engine_crash_keys.cc
index 50149fb..001f234 100644
--- a/blimp/engine/app/blimp_engine_crash_keys.cc
+++ b/blimp/engine/app/blimp_engine_crash_keys.cc
@@ -25,6 +25,7 @@
       { crash_keys::kVariations, crash_keys::kLargeSize },
 
       // //content crash keys
+      { "bad_message_reason", crash_keys::kSmallSize },
       { "channel_error_bt", crash_keys::kMediumSize },
       { "discardable-memory-allocated", crash_keys::kSmallSize },
       { "discardable-memory-free", crash_keys::kSmallSize },
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index 75e84d88..ef01cd8f 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -13,14 +13,18 @@
 
 assert(host_os == "mac")
 
+import("//build/toolchain/cc_wrapper.gni")
 import("//build/toolchain/goma.gni")
 import("//build/toolchain/toolchain.gni")
 import("//build/toolchain/concurrent_links.gni")
 
 if (use_goma) {
-  goma_prefix = "$goma_dir/gomacc "
+  assert(cc_wrapper == "", "Goma and cc_wrapper can't be used together.")
+  compiler_prefix = "$goma_dir/gomacc "
+} else if (cc_wrapper != "") {
+  compiler_prefix = cc_wrapper + " "
 } else {
-  goma_prefix = ""
+  compiler_prefix = ""
 }
 
 if (current_toolchain == default_toolchain) {
@@ -352,8 +356,8 @@
   toolchain_os = "mac"
   prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
                        root_build_dir)
-  cc = "${goma_prefix}$prefix/clang"
-  cxx = "${goma_prefix}$prefix/clang++"
+  cc = "${compiler_prefix}$prefix/clang"
+  cxx = "${compiler_prefix}$prefix/clang++"
   ld = cxx
   is_clang = true
 }
@@ -366,8 +370,8 @@
   # shipped w/ XCode instead of the one pulled from upstream.
   prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
                        root_build_dir)
-  cc = "${goma_prefix}$prefix/clang"
-  cxx = "${goma_prefix}$prefix/clang++"
+  cc = "${compiler_prefix}$prefix/clang"
+  cxx = "${compiler_prefix}$prefix/clang++"
   ld = cxx
   is_clang = true
 }
@@ -380,8 +384,8 @@
   # shipped w/ XCode instead of the one pulled from upstream.
   prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
                        root_build_dir)
-  cc = "${goma_prefix}$prefix/clang"
-  cxx = "${goma_prefix}$prefix/clang++"
+  cc = "${compiler_prefix}$prefix/clang"
+  cxx = "${compiler_prefix}$prefix/clang++"
   ld = cxx
   is_clang = true
 }
@@ -394,8 +398,8 @@
   # shipped w/ XCode instead of the one pulled from upstream.
   prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
                        root_build_dir)
-  cc = "${goma_prefix}$prefix/clang"
-  cxx = "${goma_prefix}$prefix/clang++"
+  cc = "${compiler_prefix}$prefix/clang"
+  cxx = "${compiler_prefix}$prefix/clang++"
   ld = cxx
   is_clang = true
 }
@@ -403,8 +407,8 @@
 mac_toolchain("arm") {
   toolchain_cpu = "arm"
   toolchain_os = "mac"
-  cc = "${goma_prefix}/gcc"
-  cxx = "${goma_prefix}/g++"
+  cc = "${compiler_prefix}/gcc"
+  cxx = "${compiler_prefix}/g++"
   ld = cxx
   is_clang = false
 }
@@ -414,8 +418,8 @@
   toolchain_os = "mac"
   prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
                        root_build_dir)
-  cc = "${goma_prefix}$prefix/clang"
-  cxx = "${goma_prefix}$prefix/clang++"
+  cc = "${compiler_prefix}$prefix/clang"
+  cxx = "${compiler_prefix}$prefix/clang++"
   ld = cxx
   is_clang = true
 }
@@ -423,8 +427,8 @@
 mac_toolchain("x64") {
   toolchain_cpu = "x64"
   toolchain_os = "mac"
-  cc = "${goma_prefix}/gcc"
-  cxx = "${goma_prefix}/g++"
+  cc = "${compiler_prefix}/gcc"
+  cxx = "${compiler_prefix}/g++"
   ld = cxx
   is_clang = false
 }
diff --git a/build_overrides/v8.gni b/build_overrides/v8.gni
index 5920636d..2899ad1 100644
--- a/build_overrides/v8.gni
+++ b/build_overrides/v8.gni
@@ -32,12 +32,12 @@
   ]
   if (current_cpu == "arm" || current_cpu == "x86" || current_cpu == "mipsel") {
     v8_external_startup_data_renaming_destinations = [
-      "natives_blob_32.bin",
+      "natives_blob.bin",
       "snapshot_blob_32.bin",
     ]
   } else {
     v8_external_startup_data_renaming_destinations = [
-      "natives_blob_64.bin",
+      "natives_blob.bin",
       "snapshot_blob_64.bin",
     ]
   }
diff --git a/cc/ipc/BUILD.gn b/cc/ipc/BUILD.gn
index 6eed82b6..46895f17 100644
--- a/cc/ipc/BUILD.gn
+++ b/cc/ipc/BUILD.gn
@@ -38,10 +38,12 @@
 mojom("interfaces") {
   sources = [
     "begin_frame_args.mojom",
+    "compositor_frame.mojom",
     "compositor_frame_metadata.mojom",
     "filter_operation.mojom",
     "filter_operations.mojom",
     "quads.mojom",
+    "render_pass.mojom",
     "render_pass_id.mojom",
     "returned_resource.mojom",
     "selection.mojom",
diff --git a/cc/ipc/compositor_frame.mojom b/cc/ipc/compositor_frame.mojom
new file mode 100644
index 0000000..e32e1ef1a
--- /dev/null
+++ b/cc/ipc/compositor_frame.mojom
@@ -0,0 +1,16 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module cc.mojom;
+
+import "cc/ipc/compositor_frame_metadata.mojom";
+import "cc/ipc/render_pass.mojom";
+import "cc/ipc/transferable_resource.mojom";
+
+// See src/cc/output/compositor_frame.h.
+struct CompositorFrame {
+  cc.mojom.CompositorFrameMetadata metadata;
+  array<cc.mojom.TransferableResource> resources;
+  array<cc.mojom.RenderPass> passes;
+};
diff --git a/cc/ipc/quads.mojom b/cc/ipc/quads.mojom
index 21cc0da..a5f3888e 100644
--- a/cc/ipc/quads.mojom
+++ b/cc/ipc/quads.mojom
@@ -6,10 +6,8 @@
 
 import "cc/ipc/filter_operations.mojom";
 import "cc/ipc/render_pass_id.mojom";
-import "cc/ipc/shared_quad_state.mojom";
 import "cc/ipc/surface_id.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
-import "ui/gfx/mojo/transform.mojom";
 
 struct DebugBorderQuadState {
   // Debug border color.
@@ -144,12 +142,3 @@
   array<DrawQuad> quads;
 };
 
-struct RenderPass {
-  cc.mojom.RenderPassId id;
-  gfx.mojom.Rect output_rect;
-  gfx.mojom.Rect damage_rect;
-  gfx.mojom.Transform transform_to_root_target;
-  bool has_transparent_background;
-  array<DrawQuad> quads;
-  cc.mojom.SharedQuadStateList shared_quad_states;
-};
diff --git a/cc/ipc/render_pass.mojom b/cc/ipc/render_pass.mojom
new file mode 100644
index 0000000..8d8b29a5
--- /dev/null
+++ b/cc/ipc/render_pass.mojom
@@ -0,0 +1,22 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module cc.mojom;
+
+import "cc/ipc/render_pass_id.mojom";
+import "cc/ipc/quads.mojom";
+import "cc/ipc/shared_quad_state.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
+import "ui/gfx/mojo/transform.mojom";
+
+// See cc/quads/render_pass.h.
+struct RenderPass {
+  cc.mojom.RenderPassId id;
+  gfx.mojom.Rect output_rect;
+  gfx.mojom.Rect damage_rect;
+  gfx.mojom.Transform transform_to_root_target;
+  bool has_transparent_background;
+  array<DrawQuad> quads;
+  cc.mojom.SharedQuadStateList shared_quad_states;
+};
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index fa6cd4c1..84035dc 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -782,6 +782,7 @@
     bundle_data("flash_player_plugin") {
       sources = [
         "$root_out_dir/PepperFlash/PepperFlashPlayer.plugin",
+        "$root_out_dir/PepperFlash/manifest.json",
       ]
       outputs = [
         "{{bundle_root_dir}}/Internet Plug-Ins/PepperFlash/{{source_file_part}}",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
index 19e7ddc..1400e05 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -396,8 +396,7 @@
             });
             initializeSearchBoxRecyclerViewScrollHandling();
             mRecyclerView.addItemDecoration(new CardItemDecoration(getContext()));
-            CardsLayoutOperations.updateSnippetsHeaderDisplay(mRecyclerView,
-                    mNewTabPageLayout.getPaddingTop());
+            mRecyclerView.updateSnippetsHeaderDisplay(mNewTabPageLayout.getPaddingTop());
         } else {
             initializeSearchBoxScrollHandling();
         }
@@ -475,9 +474,8 @@
                     mRecyclerView.postDelayed(mSnapScrollRunnable, SNAP_SCROLL_DELAY_MS);
                 }
                 updateSearchBoxOnScroll();
-                CardsLayoutOperations.updatePeekingCard(mRecyclerView, getHeight());
-                CardsLayoutOperations.updateSnippetsHeaderDisplay(mRecyclerView,
-                        mNewTabPageLayout.getPaddingTop());
+                mRecyclerView.updatePeekingCard();
+                mRecyclerView.updateSnippetsHeaderDisplay(mNewTabPageLayout.getPaddingTop());
             }
         });
 
@@ -815,7 +813,7 @@
         updateSearchBoxOnScroll();
 
         if (mUseCardsUi) {
-            CardsLayoutOperations.updatePeekingCard(mRecyclerView, getHeight());
+            mRecyclerView.updatePeekingCard();
         }
     }
 
@@ -1080,7 +1078,7 @@
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 
         if (mUseCardsUi) {
-            CardsLayoutOperations.updatePeekingCard(mRecyclerView, getHeight());
+            mRecyclerView.updatePeekingCard();
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java
index bbddaf57..faa44c89 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java
@@ -92,8 +92,8 @@
     /**
      * Change the width, padding and child opacity of the card to give a smooth transition as the
      * user scrolls.
-     * @param viewportHeight The height of the containing view, to calculate when the transition
-     *          should start.
+     * @param viewportHeight The height of the containing viewport, i.e. the area inside the
+     *          containing view that is available for drawing.
      */
     public void updatePeek(int viewportHeight) {
         // The peeking card's resting position is |mMaxPeekPadding| from the bottom of the screen
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardsLayoutOperations.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardsLayoutOperations.java
index 280ef9e..7570d01 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardsLayoutOperations.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardsLayoutOperations.java
@@ -5,13 +5,11 @@
 package org.chromium.chrome.browser.ntp.cards;
 
 import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.RecyclerView.ViewHolder;
 import android.view.View;
 
 import org.chromium.chrome.browser.ntp.MostVisitedLayout;
 import org.chromium.chrome.browser.ntp.NewTabPageLayout;
 import org.chromium.chrome.browser.ntp.NewTabPageUma;
-import org.chromium.chrome.browser.ntp.snippets.SnippetHeaderViewHolder;
 
 /**
  * This is a class to organise the various layout operations of the New Tab Page while using the
@@ -19,47 +17,6 @@
  * behaviour.
  */
 public class CardsLayoutOperations {
-    /**
-     * Refresh the peeking state of the first card.
-     * @param recyclerView The NewTabPageRecyclerView that contains the cards.
-     * @param viewportHeight The height of the containing view, to calculate when the transition
-     *          should start.
-     */
-    public static void updatePeekingCard(
-            final NewTabPageRecyclerView recyclerView, int viewportHeight) {
-        // Get the first snippet that could display to make the peeking card transition.
-        int firstCardIndex = 2; // 0 => above-the-fold, 1 => header, 2 => card
-        RecyclerView.ViewHolder viewHolder =
-                recyclerView.findViewHolderForAdapterPosition(firstCardIndex);
-
-        if (viewHolder == null || !(viewHolder instanceof CardViewHolder)
-                || !viewHolder.itemView.isShown()) {
-            return;
-        }
-
-        ((CardViewHolder) viewHolder).updatePeek(viewportHeight);
-    }
-
-    /**
-     * Show the snippets header when the user scrolls down and snippet articles starts reaching the
-     * top of the screen.
-     * @param recyclerView The NewTabPageRecyclerView that contains the header card.
-     * @param omniBoxHeight The height of the omnibox displayed over the NTP, we use this to offset
-     *          the start point of the transition.
-     */
-    public static void updateSnippetsHeaderDisplay(NewTabPageRecyclerView recyclerView,
-            int omniBoxHeight) {
-        // Get the snippet header view. It is always at position 1
-        ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(1);
-
-        // Start doing the calculations if the snippet header is currently shown on screen.
-        if (viewHolder == null || !(viewHolder instanceof SnippetHeaderViewHolder)) return;
-
-        ((SnippetHeaderViewHolder) viewHolder).onScrolled(omniBoxHeight);
-
-        // Update the space at the bottom, which needs to know about the height of the header.
-        recyclerView.refreshBottomSpacing();
-    }
 
     /**
      * Snaps the scroll point to the top of the screen, the top of most visited or to articles
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
index 39de6a2..e6f2003e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java
@@ -17,6 +17,7 @@
 
 import org.chromium.base.Log;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ntp.snippets.SnippetHeaderViewHolder;
 
 /**
  * Simple wrapper on top of a RecyclerView that will acquire focus when tapped.  Ensures the
@@ -179,6 +180,59 @@
         return Math.max(MIN_BOTTOM_SPACING, bottomSpacing);
     }
 
+    /**
+     * Refresh the peeking state of the first card.
+     */
+    public void updatePeekingCard() {
+        CardViewHolder firstCard = findFirstCard();
+        if (firstCard == null) return;
+
+        if (firstCard.itemView.isShown()) {
+            firstCard.updatePeek(getHeight());
+        }
+    }
+
+    /**
+     * Finds the first card in this RecyclerView.
+     * @return The viewholder for the first card or null if no card is available.
+     */
+    private CardViewHolder findFirstCard() {
+        int firstCardIndex = 2; // 0 => above-the-fold, 1 => header, 2 => card
+        ViewHolder viewHolder = findViewHolderForAdapterPosition(firstCardIndex);
+        if (!(viewHolder instanceof CardViewHolder)) return null;
+
+        return (CardViewHolder) viewHolder;
+    }
+
+    /**
+     * Show the snippets header when the user scrolls down and snippet articles starts reaching the
+     * top of the screen.
+     * @param omniBoxHeight The height of the omnibox displayed over the NTP, we use this to offset
+     *          the start point of the transition.
+     */
+    public void updateSnippetsHeaderDisplay(int omniBoxHeight) {
+        SnippetHeaderViewHolder header = findHeaderView();
+        if (header == null) return;
+
+        // Start doing the calculations if the snippet header is currently shown on screen.
+        header.onScrolled(omniBoxHeight);
+
+        // Update the space at the bottom, which needs to know about the height of the header.
+        refreshBottomSpacing();
+    }
+
+    /**
+     * Finds the header view.
+     * @return The viewholder of the header or null, if it is not present.
+     */
+    private SnippetHeaderViewHolder findHeaderView() {
+        // Get the snippet header view. It is always at position 1
+        ViewHolder viewHolder = findViewHolderForAdapterPosition(1);
+        if (!(viewHolder instanceof SnippetHeaderViewHolder)) return null;
+
+        return (SnippetHeaderViewHolder) viewHolder;
+    }
+
     /** Called when an item is in the process of being removed from the view. */
     void onItemDismissStarted(View itemView) {
         mCompensationHeight += itemView.getHeight();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
index ed965d6..a4e3c37 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
@@ -284,6 +284,6 @@
 
     @Override
     public boolean isDismissable() {
-        return true;
+        return !isPeeking();
     }
 }
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index ba9f534..d4f00b2 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -1142,6 +1142,9 @@
   <message name="IDS_SETTINGS_PEOPLE_MANAGE_SUPERVISED_USERS" desc="Label for the button that opens the supervised users dashboard.">
     Manage supervised users
   </message>
+  <message name="IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO" desc="The text on the Google profile photo of the user.">
+    Google Profile photo
+  </message>
 
   <if expr="chromeos">
     <message name="IDS_SETTINGS_PEOPLE_ENABLE_SCREENLOCK" desc="The text on the checkbox to enable screenlocker for current user.">
@@ -1186,9 +1189,6 @@
     <message name="IDS_SETTINGS_CHANGE_PICTURE_AUTHOR_TEXT" desc="Author label.">
       Photo by
     </message>
-    <message name="IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO" desc="The text on the Google profile photo of the user.">
-      Google Profile photo
-    </message>
     <message name="IDS_SETTINGS_CHANGE_PICTURE_PROFILE_LOADING_PHOTO" desc="The text on the loading stub for Google profile image.">
       Google Profile photo (loading)
     </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 191428f..717ea25 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -686,6 +686,9 @@
               ".",
               "//chrome")
     }
+    if (is_mac) {
+      deps += [ "//chrome/browser/ui/cocoa/notifications:common" ]
+    }
   }
   if (enable_themes) {
     sources +=
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 415f0ad..985df7e5 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -44,6 +44,7 @@
 #include "components/flags_ui/flags_ui_switches.h"
 #include "components/nacl/common/nacl_switches.h"
 #include "components/network_session_configurator/switches.h"
+#include "components/ntp_snippets/ntp_snippets_constants.h"
 #include "components/ntp_tiles/switches.h"
 #include "components/offline_pages/offline_page_feature.h"
 #include "components/omnibox/browser/omnibox_switches.h"
@@ -504,6 +505,38 @@
 #endif  // defined(OS_ANDROID)
 
 #if defined(OS_ANDROID)
+const FeatureEntry::FeatureParam kNTPSnippetsFeatureVariationDefault[] = {};
+const FeatureEntry::FeatureParam kNTPSnippetsFeatureVariationOnlyPersonal[] = {
+    {"fetching_personalization", "personal"},
+    {"fetching_host_restrict", "off"},
+};
+const FeatureEntry::FeatureParam
+    kNTPSnippetsFeatureVariationOnlyNonPersonalHostRestricted[] = {
+        {"fetching_personalization", "non_personal"},
+        {"fetching_host_restrict", "on"},
+};
+const FeatureEntry::FeatureParam
+    kNTPSnippetsFeatureVariationOnlyPersonalHostRestricted[] = {
+        {"fetching_personalization", "personal"},
+        {"fetching_host_restrict", "on"},
+};
+
+// TODO(jkrcal) allow for nullptr instead of the empty array.
+const FeatureEntry::FeatureVariation kNTPSnippetsFeatureVariations[] = {
+    {"", kNTPSnippetsFeatureVariationDefault,
+     0},
+    {"only personalized", kNTPSnippetsFeatureVariationOnlyPersonal,
+     arraysize(kNTPSnippetsFeatureVariationOnlyPersonal)},
+    {"only from most visited sites",
+     kNTPSnippetsFeatureVariationOnlyNonPersonalHostRestricted,
+     arraysize(kNTPSnippetsFeatureVariationOnlyPersonal)},
+    {"only personalized from most visited sites",
+     kNTPSnippetsFeatureVariationOnlyPersonalHostRestricted,
+     arraysize(kNTPSnippetsFeatureVariationOnlyPersonalHostRestricted)},
+};
+#endif  // defined(OS_ANDROID)
+
+#if defined(OS_ANDROID)
 const FeatureEntry::Choice kUpdateMenuItemSummaryChoices[] = {
     {IDS_FLAGS_UPDATE_MENU_ITEM_NO_SUMMARY, "", ""},
     {IDS_FLAGS_UPDATE_MENU_ITEM_DEFAULT_SUMMARY,
@@ -1800,7 +1833,9 @@
 #if defined(OS_ANDROID)
     {"enable-ntp-snippets", IDS_FLAGS_ENABLE_NTP_SNIPPETS_NAME,
      IDS_FLAGS_ENABLE_NTP_SNIPPETS_DESCRIPTION, kOsAndroid,
-     FEATURE_VALUE_TYPE(chrome::android::kNTPSnippetsFeature)},
+     FEATURE_WITH_VARIATIONS_VALUE_TYPE(chrome::android::kNTPSnippetsFeature,
+                                        kNTPSnippetsFeatureVariations,
+                                        ntp_snippets::kStudyName)},
 #endif  // defined(OS_ANDROID)
 #if defined(ENABLE_WEBRTC) && BUILDFLAG(RTC_USE_H264)
     {"enable-webrtc-h264-with-openh264-ffmpeg",
diff --git a/chrome/browser/autofill/autofill_server_browsertest.cc b/chrome/browser/autofill/autofill_server_browsertest.cc
index abec775..8a224b9 100644
--- a/chrome/browser/autofill/autofill_server_browsertest.cc
+++ b/chrome/browser/autofill/autofill_server_browsertest.cc
@@ -163,13 +163,13 @@
   upload.set_form_name("test_form");
 
   test::FillUploadField(upload.add_field(), 2594484045U, "one", "text", nullptr,
-                        nullptr, 2U);
+                        nullptr, 2U, nullptr);
   test::FillUploadField(upload.add_field(), 2750915947U, "two", "text", nullptr,
-                        "off", 2U);
+                        "off", 2U, nullptr);
   test::FillUploadField(upload.add_field(), 3494787134U, "three", "text",
-                        nullptr, nullptr, 2U);
+                        nullptr, nullptr, 2U, nullptr);
   test::FillUploadField(upload.add_field(), 1236501728U, "four", "text",
-                        nullptr, "off", 2U);
+                        nullptr, "off", 2U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index ff4ac047..c46d521 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -98,6 +98,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/safe_json/safe_json_parser.h"
 #include "components/signin/core/common/profile_management_switches.h"
+#include "components/subresource_filter/content/browser/content_ruleset_distributor.h"
 #include "components/subresource_filter/core/browser/ruleset_service.h"
 #include "components/subresource_filter/core/browser/subresource_filter_constants.h"
 #include "components/translate/core/browser/translate_download_manager.h"
@@ -1154,6 +1155,8 @@
       new subresource_filter::RulesetService(
           local_state(), blocking_task_runner,
           user_data_dir.Append(subresource_filter::kRulesetBaseDirectoryName)));
+  subresource_filter_ruleset_service_->RegisterDistributor(
+      base::WrapUnique(new subresource_filter::ContentRulesetDistributor));
 }
 
 void BrowserProcessImpl::CreateGCMDriver() {
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index c64ee2e1..fdd74b1e 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -53,6 +53,7 @@
 #include "chrome/browser/component_updater/pepper_flash_component_installer.h"
 #include "chrome/browser/component_updater/recovery_component_installer.h"
 #include "chrome/browser/component_updater/sth_set_component_installer.h"
+#include "chrome/browser/component_updater/subresource_filter_component_installer.h"
 #include "chrome/browser/component_updater/supervised_user_whitelist_installer.h"
 #include "chrome/browser/component_updater/swiftshader_component_installer.h"
 #include "chrome/browser/component_updater/widevine_cdm_component_installer.h"
@@ -478,6 +479,8 @@
       g_browser_process->supervised_user_whitelist_installer();
   whitelist_installer->RegisterComponents();
 
+  RegisterSubresourceFilterComponent(cus);
+
   base::FilePath path;
   if (PathService::Get(chrome::DIR_USER_DATA, &path)) {
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
index 8b900a16..8189ac38 100644
--- a/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
+++ b/chrome/browser/chromeos/system/tray_accessibility_browsertest.cc
@@ -3,10 +3,10 @@
 // found in the LICENSE file.
 
 #include "ash/common/accessibility_types.h"
+#include "ash/common/system/tray_accessibility.h"
 #include "ash/magnifier/magnification_controller.h"
 #include "ash/shell.h"
 #include "ash/system/tray/system_tray.h"
-#include "ash/system/tray_accessibility.h"
 #include "ash/system/user/login_status.h"
 #include "ash/test/shell_test_api.h"
 #include "ash/test/test_session_state_delegate.h"
diff --git a/chrome/browser/component_updater/subresource_filter_component_installer.cc b/chrome/browser/component_updater/subresource_filter_component_installer.cc
new file mode 100644
index 0000000..ddbd3bbb
--- /dev/null
+++ b/chrome/browser/component_updater/subresource_filter_component_installer.cc
@@ -0,0 +1,112 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/component_updater/subresource_filter_component_installer.h"
+
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "components/component_updater/component_updater_paths.h"
+#include "content/public/browser/browser_thread.h"
+
+using component_updater::ComponentUpdateService;
+
+namespace component_updater {
+
+// The extension id is: gcmjkmgdlgnkkcocmoeiminaijmmjnii
+const uint8_t kPublicKeySHA256[32] = {
+    0x62, 0xc9, 0xac, 0x63, 0xb6, 0xda, 0xa2, 0xe2, 0xce, 0x48, 0xc8,
+    0xd0, 0x89, 0xcc, 0x9d, 0x88, 0x02, 0x7c, 0x3e, 0x71, 0xcf, 0x5d,
+    0x6b, 0xb5, 0xdf, 0x21, 0x65, 0x82, 0x08, 0x97, 0x6a, 0x26};
+
+const char kSubresourceFilterSetFetcherManifestName[] =
+    "Subresource Filter Rules";
+
+SubresourceFilterComponentInstallerTraits::
+    SubresourceFilterComponentInstallerTraits() {}
+
+SubresourceFilterComponentInstallerTraits::
+    ~SubresourceFilterComponentInstallerTraits() {}
+
+bool SubresourceFilterComponentInstallerTraits::CanAutoUpdate() const {
+  return true;
+}
+
+// Public data is delivered via this component, no need for encryption.
+bool SubresourceFilterComponentInstallerTraits::RequiresNetworkEncryption()
+    const {
+  return false;
+}
+
+bool SubresourceFilterComponentInstallerTraits::OnCustomInstall(
+    const base::DictionaryValue& manifest,
+    const base::FilePath& install_dir) {
+  return true;  // Nothing custom here.
+}
+
+void SubresourceFilterComponentInstallerTraits::ComponentReady(
+    const base::Version& version,
+    const base::FilePath& install_dir,
+    std::unique_ptr<base::DictionaryValue> manifest) {
+  content::BrowserThread::PostBlockingPoolTask(
+      FROM_HERE, base::Bind(&SubresourceFilterComponentInstallerTraits::
+                                LoadSubresourceFilterRulesFromDisk,
+                            base::Unretained(this), install_dir, version));
+}
+
+// Called during startup and installation before ComponentReady().
+bool SubresourceFilterComponentInstallerTraits::VerifyInstallation(
+    const base::DictionaryValue& manifest,
+    const base::FilePath& install_dir) const {
+  return base::PathExists(install_dir);
+}
+
+base::FilePath
+SubresourceFilterComponentInstallerTraits::GetRelativeInstallDir() const {
+  return base::FilePath(FILE_PATH_LITERAL("SubresourceFilterRules"));
+}
+
+void SubresourceFilterComponentInstallerTraits::GetHash(
+    std::vector<uint8_t>* hash) const {
+  hash->assign(std::begin(kPublicKeySHA256), std::end(kPublicKeySHA256));
+}
+
+std::string SubresourceFilterComponentInstallerTraits::GetName() const {
+  return kSubresourceFilterSetFetcherManifestName;
+}
+
+std::string SubresourceFilterComponentInstallerTraits::GetAp() const {
+  return std::string();
+}
+
+void SubresourceFilterComponentInstallerTraits::
+    LoadSubresourceFilterRulesFromDisk(
+        const base::FilePath& subresource_filter_path,
+        const base::Version& version) {
+  if (subresource_filter_path.empty())
+    return;
+  DVLOG(1) << "Subresource Filter: Successfully read: "
+           << subresource_filter_path.value() << " " << version;
+  std::string rules;
+  base::FilePath full_path = subresource_filter_path.Append(
+      FILE_PATH_LITERAL("subresource_filter_rules.blob"));
+  if (!base::ReadFileToString(full_path, &rules)) {
+    VLOG(1) << "Failed reading from " << full_path.value();
+    return;
+  }
+  // TODO(melandory): notify SubresourceFilteringRulesService (accessing it via
+  // g_browser_process) about newely arrived data.
+}
+
+void RegisterSubresourceFilterComponent(ComponentUpdateService* cus) {
+  std::unique_ptr<ComponentInstallerTraits> traits(
+      new SubresourceFilterComponentInstallerTraits());
+  // |cus| will take ownership of |installer| during installer->Register(cus).
+  DefaultComponentInstaller* installer =
+      new DefaultComponentInstaller(std::move(traits));
+  installer->Register(cus, base::Closure());
+}
+
+}  // namespace component_updater
diff --git a/chrome/browser/component_updater/subresource_filter_component_installer.h b/chrome/browser/component_updater/subresource_filter_component_installer.h
new file mode 100644
index 0000000..6d39fc3a
--- /dev/null
+++ b/chrome/browser/component_updater/subresource_filter_component_installer.h
@@ -0,0 +1,55 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_COMPONENT_UPDATER_SUBRESOURCE_FILTER_COMPONENT_INSTALLER_H_
+#define CHROME_BROWSER_COMPONENT_UPDATER_SUBRESOURCE_FILTER_COMPONENT_INSTALLER_H_
+
+#include "components/component_updater/default_component_installer.h"
+
+namespace base {
+class FilePath;
+}  // namespace base
+
+namespace component_updater {
+
+class ComponentUpdateService;
+
+// Component for receiving Safe Browsing Subresource filtering rules.
+class SubresourceFilterComponentInstallerTraits
+    : public ComponentInstallerTraits {
+ public:
+  SubresourceFilterComponentInstallerTraits();
+
+  ~SubresourceFilterComponentInstallerTraits() override;
+
+ private:
+  friend class SubresourceFilterComponentInstallerTest;
+
+  // ComponentInstallerTraits implementation.
+  bool CanAutoUpdate() const override;
+  bool RequiresNetworkEncryption() const override;
+  bool OnCustomInstall(const base::DictionaryValue& manifest,
+                       const base::FilePath& install_dir) override;
+  bool VerifyInstallation(const base::DictionaryValue& manifest,
+                          const base::FilePath& install_dir) const override;
+  void ComponentReady(const base::Version& version,
+                      const base::FilePath& install_dir,
+                      std::unique_ptr<base::DictionaryValue> manifest) override;
+  base::FilePath GetRelativeInstallDir() const override;
+  void GetHash(std::vector<uint8_t>* hash) const override;
+  std::string GetName() const override;
+  std::string GetAp() const override;
+
+  // Reads and parses the on-disk ruleset file.
+  void LoadSubresourceFilterRulesFromDisk(const base::FilePath& file_path,
+                                          const base::Version& version);
+
+  DISALLOW_COPY_AND_ASSIGN(SubresourceFilterComponentInstallerTraits);
+};
+
+void RegisterSubresourceFilterComponent(ComponentUpdateService* cus);
+
+}  // namespace component_updater
+
+#endif  // CHROME_BROWSER_COMPONENT_UPDATER_SUBRESOURCE_FILTER_COMPONENT_INSTALLER_H_
diff --git a/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc b/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc
new file mode 100644
index 0000000..c5167228
--- /dev/null
+++ b/chrome/browser/component_updater/subresource_filter_component_installer_unittest.cc
@@ -0,0 +1,75 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/component_updater/subresource_filter_component_installer.h"
+
+#include <map>
+#include <string>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/run_loop.h"
+#include "base/strings/string_util.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace component_updater {
+
+class SubresourceFilterComponentInstallerTest : public PlatformTest {
+ public:
+  SubresourceFilterComponentInstallerTest() {}
+  void SetUp() override {
+    PlatformTest::SetUp();
+
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+
+    traits_.reset(new SubresourceFilterComponentInstallerTraits());
+  }
+
+  void WriteSubresourceFilterToFile(
+      const std::string subresource_filter_content,
+      const base::FilePath& filename) {
+    ASSERT_EQ(static_cast<int32_t>(subresource_filter_content.length()),
+              base::WriteFile(filename, subresource_filter_content.c_str(),
+                              subresource_filter_content.length()));
+  }
+
+  base::FilePath GetSubresourceFilterRulesDir() { return temp_dir_.path(); }
+
+  void LoadSubresourceFilterRules(
+      const base::DictionaryValue& manifest,
+      const base::FilePath& subresource_filters_dir) {
+    ASSERT_TRUE(traits_->VerifyInstallation(manifest, temp_dir_.path()));
+
+    const base::Version v("1.0");
+    traits_->LoadSubresourceFilterRulesFromDisk(subresource_filters_dir, v);
+    // Drain the RunLoop created by the TestBrowserThreadBundle
+    base::RunLoop().RunUntilIdle();
+  }
+
+ protected:
+  content::TestBrowserThreadBundle thread_bundle_;
+
+  base::ScopedTempDir temp_dir_;
+  std::unique_ptr<SubresourceFilterComponentInstallerTraits> traits_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SubresourceFilterComponentInstallerTest);
+};
+
+TEST_F(SubresourceFilterComponentInstallerTest, LoadEmptyFile) {
+  const base::DictionaryValue manifest;
+  const base::FilePath subresource_filters_dir(GetSubresourceFilterRulesDir());
+
+  const base::FilePath first_subresource_filter_file =
+      subresource_filters_dir.Append(
+          FILE_PATH_LITERAL("subresource_filter_rules.blob"));
+  WriteSubresourceFilterToFile(std::string(), first_subresource_filter_file);
+
+  LoadSubresourceFilterRules(manifest, subresource_filters_dir);
+}
+
+}  // namespace component_updater
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 1137176..326f4cd 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -523,7 +523,13 @@
 }
 
 #if defined(USE_PROPRIETARY_CODECS)
-IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4) {
+// Crashes on Mac only.  http://crbug.com/621857
+#if defined(OS_MACOSX)
+#define MAYBE_Playback_VideoOnly_MP4 DISABLED_Playback_VideoOnly_MP4
+#else
+#define MAYBE_Playback_VideoOnly_MP4 Playback_VideoOnly_MP4
+#endif
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_Playback_VideoOnly_MP4) {
   // MP4 without MSE is not support yet, http://crbug.com/170793.
   if (CurrentSourceType() != MSE) {
     DVLOG(0) << "Skipping test; Can only play MP4 encrypted streams by MSE.";
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm
index 3b1832c..39efa122 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -12,12 +12,14 @@
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/notifications/notification.h"
-#include "chrome/browser/notifications/notification_builder_mac.h"
 #include "chrome/browser/notifications/notification_display_service_factory.h"
 #include "chrome/browser/notifications/persistent_notification_delegate.h"
 #include "chrome/browser/notifications/platform_notification_service_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
+#import "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/url_formatter/elide_url.h"
 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificationConstants.h"
@@ -135,7 +137,6 @@
   [builder setIncognito:incognito];
 
   NSUserNotification* toast = [builder buildUserNotification];
-
   [notification_center_ deliverNotification:toast];
 }
 
@@ -147,10 +148,10 @@
   for (NSUserNotification* toast in
        [notification_center_ deliveredNotifications]) {
     NSString* toast_id =
-        [toast.userInfo objectForKey:notification_builder::kNotificationId];
+        [toast.userInfo objectForKey:notification_constants::kNotificationId];
 
     NSString* persistent_profile_id = [toast.userInfo
-        objectForKey:notification_builder::kNotificationProfileId];
+        objectForKey:notification_constants::kNotificationProfileId];
 
     if (toast_id == candidate_id &&
         persistent_profile_id == current_profile_id) {
@@ -169,10 +170,10 @@
   for (NSUserNotification* toast in
        [notification_center_ deliveredNotifications]) {
     NSString* toast_profile_id = [toast.userInfo
-        objectForKey:notification_builder::kNotificationProfileId];
+        objectForKey:notification_constants::kNotificationProfileId];
     if (toast_profile_id == current_profile_id) {
-      notifications->insert(base::SysNSStringToUTF8(
-          [toast.userInfo objectForKey:notification_builder::kNotificationId]));
+      notifications->insert(base::SysNSStringToUTF8([toast.userInfo
+          objectForKey:notification_constants::kNotificationId]));
     }
   }
   return true;
@@ -187,11 +188,18 @@
 @implementation NotificationCenterDelegate
 - (void)userNotificationCenter:(NSUserNotificationCenter*)center
        didActivateNotification:(NSUserNotification*)notification {
-  std::string notificationOrigin =
-      base::SysNSStringToUTF8([notification.userInfo
-          objectForKey:notification_builder::kNotificationOrigin]);
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDictionary:notification];
+
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+
+  std::string notificationOrigin = base::SysNSStringToUTF8(
+      [response objectForKey:notification_constants::kNotificationOrigin]);
   NSString* notificationId = [notification.userInfo
-      objectForKey:notification_builder::kNotificationId];
+      objectForKey:notification_constants::kNotificationId];
   std::string persistentNotificationId =
       base::SysNSStringToUTF8(notificationId);
   int64_t persistentId;
@@ -200,58 +208,19 @@
                << persistentNotificationId << " to integer.";
     return;
   }
-
-  NSString* profileId = [notification.userInfo
-      objectForKey:notification_builder::kNotificationProfileId];
-  NSNumber* isIncognito = [notification.userInfo
-      objectForKey:notification_builder::kNotificationIncognito];
+  std::string profileId = base::SysNSStringToUTF8(
+      [response objectForKey:notification_constants::kNotificationProfileId]);
+  NSNumber* isIncognito =
+      [response objectForKey:notification_constants::kNotificationIncognito];
 
   GURL origin(notificationOrigin);
 
-  // Initialize operation and button index for the case where the
-  // notification itself was clicked.
-  PlatformNotificationServiceImpl::NotificationOperation operation =
-      PlatformNotificationServiceImpl::NOTIFICATION_CLICK;
-  int buttonIndex = -1;
-
-  // Determine whether the user clicked on a button, and if they did, whether it
-  // was a developer-provided button or the mandatory Settings button.
-  if (notification.activationType ==
-      NSUserNotificationActivationTypeActionButtonClicked) {
-    NSArray* alternateButtons = @[];
-    if ([notification
-            respondsToSelector:@selector(_alternateActionButtonTitles)]) {
-      alternateButtons =
-          [notification valueForKey:@"_alternateActionButtonTitles"];
-    }
-
-    bool multipleButtons = (alternateButtons.count > 0);
-
-    // No developer actions, just the settings button.
-    if (!multipleButtons) {
-      operation = PlatformNotificationServiceImpl::NOTIFICATION_SETTINGS;
-      buttonIndex = -1;
-    } else {
-      // 0 based array containing.
-      // Button 1
-      // Button 2 (optional)
-      // Settings
-      NSNumber* actionIndex =
-          [notification valueForKey:@"_alternateActionIndex"];
-      operation = (actionIndex.unsignedLongValue == alternateButtons.count - 1)
-                      ? PlatformNotificationServiceImpl::NOTIFICATION_SETTINGS
-                      : PlatformNotificationServiceImpl::NOTIFICATION_CLICK;
-      buttonIndex =
-          (actionIndex.unsignedLongValue == alternateButtons.count - 1)
-              ? -1
-              : actionIndex.intValue;
-    }
-  }
-
   PlatformNotificationServiceImpl::GetInstance()
       ->ProcessPersistentNotificationOperation(
-          operation, base::SysNSStringToUTF8(profileId),
-          [isIncognito boolValue], origin, persistentId, buttonIndex);
+          static_cast<PlatformNotificationServiceImpl::NotificationOperation>(
+              operation.intValue),
+          profileId, [isIncognito boolValue], origin, persistentId,
+          buttonIndex.intValue);
 }
 
 - (BOOL)userNotificationCenter:(NSUserNotificationCenter*)center
diff --git a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc
index 12a37cd..562c655 100644
--- a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.cc
@@ -178,14 +178,16 @@
   if (abort_type == UserAbortType::ABORT_NONE)
     return;
 
-  base::TimeDelta time_to_abort = extra_info.time_to_abort;
-  DCHECK(!time_to_abort.is_zero());
+  DCHECK(extra_info.time_to_abort);
 
   // Don't log abort times if the page was backgrounded before the abort event.
-  if (!WasStartedInForegroundEventInForeground(time_to_abort, extra_info))
+  if (!WasStartedInForegroundOptionalEventInForeground(extra_info.time_to_abort,
+                                                       extra_info))
     return;
 
-  if (extra_info.time_to_commit.is_zero()) {
+  const base::TimeDelta& time_to_abort = extra_info.time_to_abort.value();
+
+  if (!extra_info.time_to_commit) {
     RecordAbortBeforeCommit(abort_type, time_to_abort);
     return;
   }
diff --git a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer_unittest.cc
index 812fb06..9fba965 100644
--- a/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer_unittest.cc
@@ -152,7 +152,18 @@
   PopulateRequiredTimingFields(&timing);
   NavigateAndCommit(GURL("https://www.google.com"));
   SimulateTimingUpdate(timing);
+
+  // The test cannot assume that abort time will be > first_paint
+  // (1 micro-sec). If the system clock is low resolution, PageLoadTracker's
+  // abort time may be <= first_paint. In that case the histogram will be
+  // logged. Thus both 0 and 1 counts of histograms are considered good.
+
   NavigateAndCommit(GURL("https://www.example.com"));
-  histogram_tester().ExpectTotalCount(
-      internal::kHistogramAbortNewNavigationBeforePaint, 0);
+
+  base::HistogramTester::CountsMap counts_map =
+      histogram_tester().GetTotalCountsForPrefix(
+          internal::kHistogramAbortNewNavigationBeforePaint);
+
+  EXPECT_TRUE(counts_map.empty() ||
+              (counts_map.size() == 1 && counts_map.begin()->second == 1));
 }
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
index cad1ee66..365e643 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
@@ -321,6 +321,13 @@
   RecordRappor(timing, info);
 }
 
+CorePageLoadMetricsObserver::FailedProvisionalLoadInfo::
+    FailedProvisionalLoadInfo()
+    : error(net::OK) {}
+
+CorePageLoadMetricsObserver::FailedProvisionalLoadInfo::
+    ~FailedProvisionalLoadInfo() {}
+
 void CorePageLoadMetricsObserver::OnFailedProvisionalLoad(
     content::NavigationHandle* navigation_handle) {
   // Only handle actual failures; provisional loads that failed due to another
@@ -344,44 +351,50 @@
     const page_load_metrics::PageLoadExtraInfo& info) {
   // Record metrics for pages which start in the foreground and are
   // backgrounded.
-  if (info.started_in_foreground && !info.first_background_time.is_zero()) {
-    if (info.time_to_commit.is_zero()) {
+  if (info.started_in_foreground && info.first_background_time) {
+    const base::TimeDelta first_background_time =
+        info.first_background_time.value();
+
+    if (!info.time_to_commit) {
       PAGE_LOAD_HISTOGRAM(internal::kHistogramBackgroundBeforeCommit,
-                          info.first_background_time);
+                          first_background_time);
     } else if (timing.first_paint.is_zero() ||
-               timing.first_paint > info.first_background_time) {
+               timing.first_paint > first_background_time) {
       PAGE_LOAD_HISTOGRAM(internal::kHistogramBackgroundBeforePaint,
-                          info.first_background_time);
+                          first_background_time);
     }
     if (!timing.parse_start.is_zero() &&
-        info.first_background_time >= timing.parse_start &&
+        first_background_time >= timing.parse_start &&
         (timing.parse_stop.is_zero() ||
-         timing.parse_stop > info.first_background_time)) {
+         timing.parse_stop > first_background_time)) {
       PAGE_LOAD_HISTOGRAM(internal::kHistogramBackgroundDuringParse,
-                          info.first_background_time);
+                          first_background_time);
     }
   }
 
   if (failed_provisional_load_info_.error != net::OK) {
+    DCHECK(failed_provisional_load_info_.interval);
+
     // Ignores a background failed provisional load.
-    if (WasStartedInForegroundEventInForeground(
+    if (WasStartedInForegroundOptionalEventInForeground(
             failed_provisional_load_info_.interval, info)) {
       PAGE_LOAD_HISTOGRAM(internal::kHistogramFailedProvisionalLoad,
-                          failed_provisional_load_info_.interval);
+                          failed_provisional_load_info_.interval.value());
     }
   }
 
   // The rest of the histograms require the load to have committed and be
   // relevant. If |timing.IsEmpty()|, then this load was not tracked by the
   // renderer.
-  if (info.time_to_commit.is_zero() || timing.IsEmpty())
+  if (!info.time_to_commit || timing.IsEmpty())
     return;
 
-  if (WasStartedInForegroundEventInForeground(info.time_to_commit, info)) {
-    PAGE_LOAD_HISTOGRAM(internal::kHistogramCommit, info.time_to_commit);
+  const base::TimeDelta time_to_commit = info.time_to_commit.value();
+  if (WasStartedInForegroundOptionalEventInForeground(info.time_to_commit,
+                                                      info)) {
+    PAGE_LOAD_HISTOGRAM(internal::kHistogramCommit, time_to_commit);
   } else {
-    PAGE_LOAD_HISTOGRAM(internal::kBackgroundHistogramCommit,
-                        info.time_to_commit);
+    PAGE_LOAD_HISTOGRAM(internal::kBackgroundHistogramCommit, time_to_commit);
   }
   if (!timing.dom_content_loaded_event_start.is_zero()) {
     if (WasStartedInForegroundEventInForeground(
@@ -425,13 +438,13 @@
     // - Opened in the background.
     // - Moved to the foreground prior to the first paint.
     // - Not moved back to the background prior to the first paint.
-    if (!info.started_in_foreground && !info.first_foreground_time.is_zero() &&
-        timing.first_paint > info.first_foreground_time &&
-        (info.first_background_time.is_zero() ||
-         timing.first_paint < info.first_background_time)) {
+    if (!info.started_in_foreground && info.first_foreground_time &&
+        timing.first_paint > info.first_foreground_time.value() &&
+        (!info.first_background_time ||
+         timing.first_paint < info.first_background_time.value())) {
       PAGE_LOAD_HISTOGRAM(
           internal::kHistogramForegroundToFirstPaint,
-          timing.first_paint - info.first_foreground_time);
+          timing.first_paint - info.first_foreground_time.value());
     }
   }
   if (!timing.first_text_paint.is_zero()) {
@@ -521,13 +534,13 @@
   // Log time to first foreground / time to first background. Log counts that we
   // started a relevant page load in the foreground / background.
   if (info.started_in_foreground) {
-    if (!info.first_background_time.is_zero())
+    if (info.first_background_time)
       PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstBackground,
-                          info.first_background_time);
+                          info.first_background_time.value());
   } else {
-    if (!info.first_foreground_time.is_zero())
+    if (info.first_foreground_time)
       PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstForeground,
-                          info.first_foreground_time);
+                          info.first_foreground_time.value());
   }
 }
 
@@ -543,7 +556,7 @@
   rappor::RapporService* rappor_service = g_browser_process->rappor_service();
   if (!rappor_service)
     return;
-  if (info.time_to_commit.is_zero())
+  if (!info.time_to_commit)
     return;
   DCHECK(!info.committed_url.is_empty());
   // Log the eTLD+1 of sites that show poor loading performance.
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
index 2b6a48d..1bae6eb4 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
@@ -85,10 +85,11 @@
   // Information related to failed provisional loads.
   // Populated in OnFailedProvisionalLoad and accessed in OnComplete.
   struct FailedProvisionalLoadInfo {
-    base::TimeDelta interval;
+    base::Optional<base::TimeDelta> interval;
     net::Error error;
 
-    FailedProvisionalLoadInfo() : error(net::OK) {}
+    FailedProvisionalLoadInfo();
+    ~FailedProvisionalLoadInfo();
   };
 
   void RecordTimingHistograms(const page_load_metrics::PageLoadTiming& timing,
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
index eefc6bf..d66de858 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
 #include "chrome/test/base/testing_browser_process.h"
+#include "components/page_load_metrics/browser/page_load_metrics_util.h"
 #include "components/rappor/rappor_utils.h"
 #include "components/rappor/test_rappor_service.h"
 
@@ -238,10 +239,51 @@
   histogram_tester().ExpectTotalCount(internal::kHistogramFirstTextPaint, 0);
 }
 
+TEST_F(CorePageLoadMetricsObserverTest,
+       BackgroundCommitHistogramClockResolutionNonDeterministic) {
+  base::TimeDelta first_layout = base::TimeDelta::FromMilliseconds(1);
+
+  page_load_metrics::PageLoadTiming timing;
+  timing.navigation_start = base::Time::FromDoubleT(1);
+  timing.first_layout = first_layout;
+  PopulateRequiredTimingFields(&timing);
+
+  // Start a provisional load.
+  GURL url(kDefaultTestUrl2);
+  content::RenderFrameHostTester* rfh_tester =
+      content::RenderFrameHostTester::For(main_rfh());
+  rfh_tester->SimulateNavigationStart(url);
+
+  // Background and then commit.
+  web_contents()->WasHidden();
+  rfh_tester->SimulateNavigationCommit(url);
+  SimulateTimingUpdate(timing);
+  rfh_tester->SimulateNavigationStop();
+
+  page_load_metrics::PageLoadExtraInfo info =
+      GetPageLoadExtraInfoForCommittedLoad();
+
+  // Navigate again to force histograms to be logged.
+  NavigateAndCommit(GURL(kDefaultTestUrl));
+
+  // If the system clock is low resolution PageLoadTracker's commit_time_ may
+  // be = first_background_time_.
+  if (page_load_metrics::WasStartedInForegroundOptionalEventInForeground(
+          info.time_to_commit, info)) {
+    histogram_tester().ExpectTotalCount(internal::kBackgroundHistogramCommit,
+                                        0);
+    histogram_tester().ExpectTotalCount(internal::kHistogramCommit, 1);
+  } else {
+    histogram_tester().ExpectTotalCount(internal::kBackgroundHistogramCommit,
+                                        1);
+    histogram_tester().ExpectTotalCount(internal::kHistogramCommit, 0);
+  }
+}
+
 TEST_F(CorePageLoadMetricsObserverTest, OnlyBackgroundLaterEvents) {
   page_load_metrics::PageLoadTiming timing;
   timing.navigation_start = base::Time::FromDoubleT(1);
-  // Set these events at 1 microsecond so they are definitely occur before we
+  // Set these events at 1 microsecond so they definitely occur before we
   // background the tab later in the test.
   timing.response_start = base::TimeDelta::FromMicroseconds(1);
   timing.dom_loading = base::TimeDelta::FromMicroseconds(1);
@@ -250,7 +292,7 @@
   NavigateAndCommit(GURL(kDefaultTestUrl));
   SimulateTimingUpdate(timing);
 
-  // Background the tab, then forground it.
+  // Background the tab, then foreground it.
   web_contents()->WasHidden();
   web_contents()->WasShown();
   timing.first_layout = base::TimeDelta::FromSeconds(3);
@@ -258,12 +300,33 @@
   PopulateRequiredTimingFields(&timing);
   SimulateTimingUpdate(timing);
 
+  // If the system clock is low resolution, PageLoadTracker's
+  // first_background_time_ may be same as other times such as
+  // dom_content_loaded_event_start.
+  page_load_metrics::PageLoadExtraInfo info =
+      GetPageLoadExtraInfoForCommittedLoad();
+
   // Navigate again to force histogram recording.
   NavigateAndCommit(GURL(kDefaultTestUrl2));
 
   histogram_tester().ExpectTotalCount(internal::kBackgroundHistogramCommit, 0);
-  histogram_tester().ExpectTotalCount(
-      internal::kBackgroundHistogramDomContentLoaded, 0);
+
+  if (page_load_metrics::WasStartedInForegroundEventInForeground(
+          timing.dom_content_loaded_event_start, info)) {
+    histogram_tester().ExpectTotalCount(internal::kHistogramDomContentLoaded,
+                                        1);
+    histogram_tester().ExpectBucketCount(
+        internal::kHistogramDomContentLoaded,
+        timing.dom_content_loaded_event_start.InMilliseconds(), 1);
+    histogram_tester().ExpectTotalCount(
+        internal::kBackgroundHistogramDomContentLoaded, 0);
+  } else {
+    histogram_tester().ExpectTotalCount(
+        internal::kBackgroundHistogramDomContentLoaded, 1);
+    histogram_tester().ExpectTotalCount(internal::kHistogramDomContentLoaded,
+                                        0);
+  }
+
   histogram_tester().ExpectTotalCount(internal::kBackgroundHistogramLoad, 0);
   histogram_tester().ExpectTotalCount(internal::kBackgroundHistogramFirstLayout,
                                       1);
@@ -277,10 +340,6 @@
       timing.first_text_paint.InMilliseconds(), 1);
 
   histogram_tester().ExpectTotalCount(internal::kHistogramCommit, 1);
-  histogram_tester().ExpectTotalCount(internal::kHistogramDomContentLoaded, 1);
-  histogram_tester().ExpectBucketCount(
-      internal::kHistogramDomContentLoaded,
-      timing.dom_content_loaded_event_start.InMilliseconds(), 1);
   histogram_tester().ExpectTotalCount(internal::kHistogramLoad, 0);
   histogram_tester().ExpectTotalCount(internal::kHistogramFirstLayout, 0);
   histogram_tester().ExpectTotalCount(internal::kHistogramFirstTextPaint, 0);
@@ -345,10 +404,10 @@
   // Test that failed provisional event does not get logged in the
   // histogram if it happened in the background
   GURL url(kDefaultTestUrl);
+  web_contents()->WasHidden();
   content::RenderFrameHostTester* rfh_tester =
       content::RenderFrameHostTester::For(main_rfh());
   rfh_tester->SimulateNavigationStart(url);
-  web_contents()->WasHidden();
   rfh_tester->SimulateNavigationError(url, net::ERR_TIMED_OUT);
   rfh_tester->SimulateNavigationStop();
 
diff --git a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
index e79c5a7b..bc18f8e 100644
--- a/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.cc
@@ -172,7 +172,7 @@
 void DocumentWritePageLoadMetricsObserver::OnComplete(
     const page_load_metrics::PageLoadTiming& timing,
     const page_load_metrics::PageLoadExtraInfo& info) {
-  if (info.time_to_commit.is_zero() || timing.IsEmpty())
+  if (!info.time_to_commit || timing.IsEmpty())
     return;
   if (info.metadata.behavior_flags &
       blink::WebLoadingBehaviorFlag::WebLoadingBehaviorDocumentWriteEvaluator) {
diff --git a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
index fdc51b77..11c35bd 100644
--- a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
@@ -179,27 +179,29 @@
   }
 }
 
-bool WasAbortedInForeground(UserAbortType abort_type,
-                            base::TimeDelta time_to_abort,
-                            const page_load_metrics::PageLoadExtraInfo& info) {
+bool WasAbortedInForeground(
+    UserAbortType abort_type,
+    const base::Optional<base::TimeDelta>& time_to_abort,
+    const page_load_metrics::PageLoadExtraInfo& info) {
+  if (!time_to_abort)
+    return false;
   if (abort_type == UserAbortType::ABORT_NONE)
     return false;
-  // This is a modified version of WasStartedInForegroundEventInForeground,
-  // which does not check time_to_abort is non-zero
-  // TODO(mushan): change back with WasStartedInForegroundEventInForeground
-  // once crbug.com/616901 is addressed
-  if (info.started_in_foreground &&
-      (info.first_background_time.is_zero() ||
-       time_to_abort < info.first_background_time))
+  if (WasStartedInForegroundOptionalEventInForeground(time_to_abort, info))
     return true;
   if (!info.started_in_foreground)
     return false;
-  DCHECK_GT(time_to_abort, info.first_background_time);
-  base::TimeDelta bg_abort_delta = time_to_abort - info.first_background_time;
+
+  const base::TimeDelta time_to_abort_val = time_to_abort.value();
+  const base::TimeDelta time_to_first_background =
+      info.first_background_time.value();
+  DCHECK_GT(time_to_abort_val, time_to_first_background);
+  base::TimeDelta background_abort_delta =
+      time_to_abort_val - time_to_first_background;
   // Consider this a foregrounded abort if it occurred within 100ms of a
   // background. This is needed for closing some tabs, where the signal for
   // background is often slightly ahead of the signal for close.
-  if (bg_abort_delta.InMilliseconds() < 100)
+  if (background_abort_delta.InMilliseconds() < 100)
     return true;
   return false;
 }
@@ -222,7 +224,7 @@
     return time_to_interaction + base::TimeDelta::FromMilliseconds(1000) >
            time_to_abort;
   } else {
-    return time_to_interaction >= time_to_abort;
+    return time_to_interaction > time_to_abort;
   }
 }
 
@@ -479,10 +481,10 @@
   // consistency with core PageLoad metrics, we ignore non-render-tracked
   // loads when tracking aborts after commit.
   UserAbortType abort_type = extra_info.abort_type;
-  base::TimeDelta time_to_abort = extra_info.time_to_abort;
-  if (!WasAbortedInForeground(abort_type, time_to_abort, extra_info))
+  if (!WasAbortedInForeground(abort_type, extra_info.time_to_abort, extra_info))
     return;
 
+  base::TimeDelta time_to_abort = extra_info.time_to_abort.value();
   if (extra_info.committed_url.is_empty()) {
     LogProvisionalAborts(abort_type, time_to_abort);
     return;
diff --git a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc
index f8bcb25..d8cb1117 100644
--- a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer_unittest.cc
@@ -7,6 +7,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
+#include "components/page_load_metrics/browser/page_load_metrics_util.h"
 
 namespace {
 const char kExampleUrl[] = "http://www.example.com/";
@@ -427,16 +428,25 @@
   NavigateAndCommit(GURL("https://www.google.com/search#q=test"));
   NavigateAndCommit(GURL(kExampleUrl));
 
-  SimulateTimingUpdate(timing);
   web_contents()->WasHidden();
+  SimulateTimingUpdate(timing);
 
-  // Navigate again to force logging.
-  NavigateAndCommit(GURL("https://www.final.com"));
-  histogram_tester().ExpectTotalCount(internal::kHistogramFromGWSFirstTextPaint,
-                                      1);
-  histogram_tester().ExpectBucketCount(
-      internal::kHistogramFromGWSFirstTextPaint,
-      timing.first_text_paint.InMilliseconds(), 1);
+  page_load_metrics::PageLoadExtraInfo info =
+      GetPageLoadExtraInfoForCommittedLoad();
+
+  // If the system clock is low resolution PageLoadTracker's background_time_
+  // may be < timing.first_text_paint.
+  if (page_load_metrics::WasStartedInForegroundEventInForeground(
+          timing.first_text_paint, info)) {
+    histogram_tester().ExpectTotalCount(
+        internal::kHistogramFromGWSFirstTextPaint, 1);
+    histogram_tester().ExpectBucketCount(
+        internal::kHistogramFromGWSFirstTextPaint,
+        timing.first_text_paint.InMilliseconds(), 1);
+  } else {
+    histogram_tester().ExpectTotalCount(
+        internal::kHistogramFromGWSFirstTextPaint, 0);
+  }
 }
 
 TEST_F(FromGWSPageLoadMetricsObserverTest, UnknownNavigationBeforeCommit) {
@@ -599,9 +609,20 @@
   PopulateRequiredTimingFields(&timing);
   NavigateAndCommit(GURL("https://example.test"));
   SimulateTimingUpdate(timing);
+
+  // The test cannot assume that abort time will be > first_paint
+  // (1 micro-sec). If the system clock is low resolution, PageLoadTracker's
+  // abort time may be <= first_paint. In that case the histogram will be
+  // logged. Thus both 0 and 1 counts of histograms are considered good.
+
   NavigateAndCommit(GURL("https://example.test2"));
-  histogram_tester().ExpectTotalCount(
-      internal::kHistogramFromGWSAbortNewNavigationBeforePaint, 0);
+
+  base::HistogramTester::CountsMap counts_map =
+      histogram_tester().GetTotalCountsForPrefix(
+          internal::kHistogramFromGWSAbortNewNavigationBeforePaint);
+
+  EXPECT_TRUE(counts_map.empty() ||
+              (counts_map.size() == 1 && counts_map.begin()->second == 1));
 }
 
 TEST_F(FromGWSPageLoadMetricsObserverTest, NewNavigationBeforeInteraction) {
diff --git a/chrome/browser/page_load_metrics/observers/https_engagement_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/https_engagement_page_load_metrics_observer.cc
index 1eba05b..02c25e7 100644
--- a/chrome/browser/page_load_metrics/observers/https_engagement_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/https_engagement_page_load_metrics_observer.cc
@@ -38,8 +38,7 @@
 void HttpsEngagementPageLoadMetricsObserver::OnComplete(
     const page_load_metrics::PageLoadTiming& timing,
     const page_load_metrics::PageLoadExtraInfo& extra_info) {
-  if (!extra_info.committed_url.is_valid() ||
-      extra_info.time_to_commit.is_zero())
+  if (!extra_info.committed_url.is_valid() || !extra_info.time_to_commit)
     return;
 
   // Don't record anything if the user never saw it.
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
index 28a7c22a..90854b0 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
@@ -130,4 +130,9 @@
   return histogram_tester_;
 }
 
+const PageLoadExtraInfo
+PageLoadMetricsObserverTestHarness::GetPageLoadExtraInfoForCommittedLoad() {
+  return observer_->GetPageLoadExtraInfoForCommittedLoad();
+}
+
 }  // namespace page_load_metrics
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
index 22ea6a5..3f44f355 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
@@ -47,6 +47,9 @@
 
   const base::HistogramTester& histogram_tester() const;
 
+  // Gets the PageLoadExtraInfo for the committed_load_ in observer_.
+  const PageLoadExtraInfo GetPageLoadExtraInfoForCommittedLoad();
+
  private:
   base::HistogramTester histogram_tester_;
   MetricsWebContentsObserver* observer_;
diff --git a/chrome/browser/resources/md_user_manager/create_profile.html b/chrome/browser/resources/md_user_manager/create_profile.html
index 80342b3..0355ce2 100644
--- a/chrome/browser/resources/md_user_manager/create_profile.html
+++ b/chrome/browser/resources/md_user_manager/create_profile.html
@@ -1,6 +1,7 @@
 <link rel="import" href="/import_supervised_user.html">
 <link rel="import" href="/profile_browser_proxy.html">
 <link rel="import" href="/shared_styles.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
 <link rel="import" href="chrome://resources/html/action_link.html">
 <link rel="import" href="chrome://resources/html/cr.html">
@@ -87,29 +88,6 @@
         width: 300px;
       }
 
-      #icons {
-        display: flex;
-        flex-wrap: wrap;
-        margin: -12px;
-      }
-
-      #icons paper-button {
-        --paper-button: {
-          background: var(--paper-grey-300);
-        };
-        --paper-button-flat-keyboard-focus: {
-          background: var(--paper-grey-400);
-        };
-        border: var(--user-manager-separator-line);
-        margin: 12px;
-        min-width: 0;
-        padding: 6px 4px;
-      }
-
-      #icons paper-button[active] {
-        border-color: var(--google-blue-500);
-      }
-
       paper-checkbox {
         --paper-checkbox-checked-color: var(--google-blue-500);
         --paper-checkbox-label-spacing: 16px;
@@ -180,15 +158,9 @@
       <paper-input id="nameInput" value="{{profileName_}}" pattern=".*\S.*"
           no-label-float auto-validate>
       </paper-input>
-      <div id="icons">
-        <template is="dom-repeat" items="[[availableIcons_]]">
-          <paper-button toggles on-tap="onIconTap_"
-              data-icon-url$="[[item.url]]"
-              active="[[isActiveIcon_(item.url, profileIconUrl_)]]">
-            <img src="[[item.url]]" alt="[[item.label]]">
-          </paper-button>
-        </template>
-      </div>
+      <cr-profile-avatar-selector avatars="[[availableIcons_]]"
+          selected-avatar-url="{{profileIconUrl_}}">
+      </cr-profile-avatar-selector>
       <paper-checkbox checked="{{isSupervised_}}">
         $i18n{manageProfilesSupervisedSignedInLabel}
       </paper-checkbox>
diff --git a/chrome/browser/resources/md_user_manager/create_profile.js b/chrome/browser/resources/md_user_manager/create_profile.js
index 8ffd25b..2b57380 100644
--- a/chrome/browser/resources/md_user_manager/create_profile.js
+++ b/chrome/browser/resources/md_user_manager/create_profile.js
@@ -374,24 +374,6 @@
   },
 
   /**
-   * Handler for when the user clicks a new profile icon.
-   * @param {!Event} event
-   * @private
-   */
-  onIconTap_: function(event) {
-    var element = Polymer.dom(event).rootTarget;
-
-    if (element.nodeName == 'IMG')
-      this.profileIconUrl_ = element.src;
-    else if (element.dataset && element.dataset.iconUrl)
-      this.profileIconUrl_ = element.dataset.iconUrl;
-
-    // Button toggle state is controlled by the selected icon URL. Prevent
-    // tap events from changing the toggle state.
-    event.preventDefault();
-  },
-
-  /**
    * Handles profile create/import success message pushed by the browser.
    * @param {!ProfileInfo} profileInfo Details of the created/imported profile.
    * @private
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.html b/chrome/browser/resources/settings/people_page/manage_profile.html
index 8cdaabcc..a191fbc 100644
--- a/chrome/browser/resources/settings/people_page/manage_profile.html
+++ b/chrome/browser/resources/settings/people_page/manage_profile.html
@@ -1,7 +1,6 @@
+<link rel="import" href="chrome://resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html">
-<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/shadow.html">
 <link rel="import" href="/people_page/manage_profile_browser_proxy.html">
@@ -10,37 +9,13 @@
 <dom-module id="settings-manage-profile">
   <template>
     <style include="settings-shared">
-      #availableIcons {
+      #selector {
+        --avatar-selector-avatar-hovered: {
+          @apply(--shadow-elevation-2dp);
+        };
         -webkit-margin-start: 16px;
         margin-top: 16px;
-        max-width: 600px;
-      }
-
-      #selector {
-        display: flex;
-        flex-wrap: wrap;
-      }
-
-      /* Special style for Manage Profile icon grid buttons only. */
-      paper-button {
-        align-items: center;
-        background-color: var(--paper-grey-300);
-        border: 1px solid var(--paper-grey-300);
-        border-radius: 4px;
-        display: flex;
-        height: 48px;
-        justify-content: center;
-        margin: 8px;
-        padding: 0;
-        width: 48px;
-      }
-
-      paper-button:hover {
-        @apply(--shadow-elevation-2dp);
-      }
-
-      paper-button.iron-selected {
-        border: 1px solid var(--google-blue-500);
+        max-width: 624px;
       }
     </style>
     <div class="settings-box first">
@@ -48,16 +23,10 @@
           auto-validate required on-change="onProfileNameChanged_">
       </paper-input>
     </div>
-    <div id="availableIcons">
-      <iron-selector id="selector" on-iron-activate="onIconActivate_"
-          selected="[[profileIconUrl]]" attr-for-selected="data-icon-url">
-        <template is="dom-repeat" items="[[availableIconUrls]]">
-          <paper-button data-icon-url$="[[item]]">
-            <img src="[[item]]">
-          </paper-button>
-        </template>
-      </iron-selector>
-    </div>
+    <cr-profile-avatar-selector id="selector" avatars="[[availableIcons]]"
+        selected-avatar-url="{{profileIconUrl}}"
+        on-iron-activate="onIconActivate_">
+    </cr-profile-avatar-selector>
   </template>
   <script src="manage_profile.js"></script>
 </dom-module>
diff --git a/chrome/browser/resources/settings/people_page/manage_profile.js b/chrome/browser/resources/settings/people_page/manage_profile.js
index 2851f68..7028491 100644
--- a/chrome/browser/resources/settings/people_page/manage_profile.js
+++ b/chrome/browser/resources/settings/people_page/manage_profile.js
@@ -27,7 +27,7 @@
      * The available icons for selection.
      * @type {!Array<string>}
      */
-    availableIconUrls: {
+    availableIcons: {
       type: Array,
       value: function() { return []; },
     },
@@ -45,8 +45,8 @@
 
   /** @override */
   attached: function() {
-    var setIcons = function(iconUrls) {
-      this.availableIconUrls = iconUrls;
+    var setIcons = function(icons) {
+      this.availableIcons = icons;
     }.bind(this);
 
     this.addWebUIListener('available-icons-changed', setIcons);
@@ -67,14 +67,12 @@
   },
 
   /**
-   * Handler for when the an image is activated.
+   * Handler for when an avatar is activated.
    * @param {!Event} event
    * @private
    */
   onIconActivate_: function(event) {
-    /** @type {{iconUrl: string}} */
-    var buttonData = event.detail.item.dataset;
-    this.browserProxy_.setProfileIconAndName(buttonData.iconUrl,
+    this.browserProxy_.setProfileIconAndName(event.detail.selected,
                                              this.profileName);
   },
 });
diff --git a/chrome/browser/subresource_filter/OWNERS b/chrome/browser/subresource_filter/OWNERS
new file mode 100644
index 0000000..ef69995
--- /dev/null
+++ b/chrome/browser/subresource_filter/OWNERS
@@ -0,0 +1,3 @@
+battre@chromium.org
+engedy@chromium.org
+melandory@chromium.org
diff --git a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
index 123c9f7..ab16641b 100644
--- a/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_browsertest.cc
@@ -2,11 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <algorithm>
+#include <iterator>
+#include <utility>
+
 #include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/subresource_filter/core/browser/ruleset_distributor.h"
+#include "components/subresource_filter/core/browser/ruleset_service.h"
 #include "components/subresource_filter/core/browser/subresource_filter_features.h"
 #include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
 #include "content/public/browser/render_frame_host.h"
@@ -16,11 +26,37 @@
 
 namespace subresource_filter {
 
+namespace {
+
+class RulesetDistributionListener : public RulesetDistributor {
+ public:
+  RulesetDistributionListener() {}
+  ~RulesetDistributionListener() override {}
+
+  void AwaitDistribution() {
+    base::RunLoop run_loop;
+    quit_closure_ = run_loop.QuitClosure();
+    run_loop.Run();
+  }
+
+ private:
+  void PublishNewVersion(base::File) override {
+    if (!quit_closure_.is_null())
+      quit_closure_.Run();
+  }
+
+  base::Closure quit_closure_;
+
+  DISALLOW_COPY_AND_ASSIGN(RulesetDistributionListener);
+};
+
+}  // namespace
+
 using subresource_filter::testing::ScopedSubresourceFilterFeatureToggle;
 
 class SubresourceFilterBrowserTest : public InProcessBrowserTest {
  public:
-  SubresourceFilterBrowserTest() {}
+  SubresourceFilterBrowserTest() : ruleset_content_version_(0) {}
   ~SubresourceFilterBrowserTest() override {}
 
  protected:
@@ -41,39 +77,68 @@
     return nullptr;
   }
 
-  void ExpectScriptResourceWasNotLoaded(content::RenderFrameHost* rfh) {
-    bool script_resource_was_not_loaded;
-    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-        rfh, "domAutomationController.send(!document.scriptExecuted)",
-        &script_resource_was_not_loaded));
-    EXPECT_TRUE(script_resource_was_not_loaded);
+  bool WasScriptResourceLoaded(content::RenderFrameHost* rfh) {
+    DCHECK(rfh);
+    bool script_resource_was_loaded;
+    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
+        rfh, "domAutomationController.send(!!document.scriptExecuted)",
+        &script_resource_was_loaded));
+    return script_resource_was_loaded;
+  }
+
+  void SetRulesetToDisallowURLsWithPathSuffix(const std::string& suffix) {
+    static_assert(sizeof(char) == sizeof(uint8_t), "Assumed char was byte.");
+    std::vector<uint8_t> buffer;
+    std::transform(suffix.begin(), suffix.end(), std::back_inserter(buffer),
+                   [](char c) { return static_cast<uint8_t>(c); });
+    RulesetDistributionListener* listener = new RulesetDistributionListener();
+    g_browser_process->subresource_filter_ruleset_service()
+        ->RegisterDistributor(base::WrapUnique(listener));
+    g_browser_process->subresource_filter_ruleset_service()
+        ->StoreAndPublishUpdatedRuleset(
+            std::move(buffer), base::IntToString(++ruleset_content_version_));
+    listener->AwaitDistribution();
   }
 
  private:
   std::unique_ptr<ScopedSubresourceFilterFeatureToggle> scoped_feature_toggle_;
+  int ruleset_content_version_;
 
   DISALLOW_COPY_AND_ASSIGN(SubresourceFilterBrowserTest);
 };
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, MainFrameActivation) {
   const GURL url(ui_test_utils::GetTestUrl(
-      base::FilePath().AppendASCII("subresource_filter"),
-      base::FilePath().AppendASCII("frame_with_included_script.html")));
+      base::FilePath(FILE_PATH_LITERAL("subresource_filter")),
+      base::FilePath(FILE_PATH_LITERAL("frame_with_included_script.html"))));
+
+  SetRulesetToDisallowURLsWithPathSuffix("suffix-that-does-not-match-anything");
   ui_test_utils::NavigateToURL(browser(), url);
-  ExpectScriptResourceWasNotLoaded(web_contents()->GetMainFrame());
+  EXPECT_TRUE(WasScriptResourceLoaded(web_contents()->GetMainFrame()));
+
+  SetRulesetToDisallowURLsWithPathSuffix("included_script.js");
+  ui_test_utils::NavigateToURL(browser(), url);
+  EXPECT_FALSE(WasScriptResourceLoaded(web_contents()->GetMainFrame()));
+
+  // The main frame document should never be filtered.
+  SetRulesetToDisallowURLsWithPathSuffix("frame_with_included_script.html");
+  ui_test_utils::NavigateToURL(browser(), url);
+  EXPECT_TRUE(WasScriptResourceLoaded(web_contents()->GetMainFrame()));
 }
 
 IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, SubFrameActivation) {
   const GURL url(ui_test_utils::GetTestUrl(
       base::FilePath().AppendASCII("subresource_filter"),
       base::FilePath().AppendASCII("frame_set.html")));
+
+  SetRulesetToDisallowURLsWithPathSuffix("included_script.js");
   ui_test_utils::NavigateToURL(browser(), url);
 
   const char* kSubframeNames[] = {"one", "two"};
   for (const char* subframe_name : kSubframeNames) {
     content::RenderFrameHost* frame = FindFrameByName(subframe_name);
     ASSERT_TRUE(frame);
-    ExpectScriptResourceWasNotLoaded(frame);
+    EXPECT_FALSE(WasScriptResourceLoaded(frame));
   }
 }
 
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
index 6054766..9844e10 100644
--- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -21,6 +21,7 @@
 #include "ash/common/system/date/clock_observer.h"
 #include "ash/common/system/tray/system_tray_delegate.h"
 #include "ash/common/system/tray/wm_system_tray_notifier.h"
+#include "ash/common/system/tray_accessibility.h"
 #include "ash/common/system/update/update_observer.h"
 #include "ash/common/system/volume_control_delegate.h"
 #include "ash/common/wm_shell.h"
@@ -33,7 +34,6 @@
 #include "ash/system/ime/ime_observer.h"
 #include "ash/system/tray/system_tray.h"
 #include "ash/system/tray/system_tray_notifier.h"
-#include "ash/system/tray_accessibility.h"
 #include "ash/system/user/login_status.h"
 #include "ash/system/user/user_observer.h"
 #include "ash/wm/lock_state_controller.h"
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index d0d1d43a..b0fe57f 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -79,7 +79,7 @@
 #endif
 
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #endif
 
 using content::NavigationEntry;
diff --git a/chrome/browser/ui/cocoa/notifications/BUILD.gn b/chrome/browser/ui/cocoa/notifications/BUILD.gn
new file mode 100644
index 0000000..57a45135
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+static_library("common") {
+  sources = [
+    "notification_builder_mac.h",
+    "notification_builder_mac.mm",
+    "notification_constants_mac.h",
+    "notification_constants_mac.mm",
+    "notification_response_builder_mac.h",
+    "notification_response_builder_mac.mm",
+  ]
+
+  deps = [
+    "//base",
+    "//chrome:strings",
+    "//ui/base:base",
+  ]
+}
diff --git a/chrome/browser/notifications/notification_builder_mac.h b/chrome/browser/ui/cocoa/notifications/notification_builder_mac.h
similarity index 83%
rename from chrome/browser/notifications/notification_builder_mac.h
rename to chrome/browser/ui/cocoa/notifications/notification_builder_mac.h
index 692e021..c9d5042 100644
--- a/chrome/browser/notifications/notification_builder_mac.h
+++ b/chrome/browser/ui/cocoa/notifications/notification_builder_mac.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_BUILDER_MAC_H_
-#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_BUILDER_MAC_H_
+#ifndef CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_BUILDER_MAC_H_
+#define CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_BUILDER_MAC_H_
 
 #import <Foundation/Foundation.h>
 
@@ -11,13 +11,6 @@
 
 @class NSUserNotification;
 
-namespace notification_builder {
-extern NSString* const kNotificationOrigin;
-extern NSString* const kNotificationId;
-extern NSString* const kNotificationProfileId;
-extern NSString* const kNotificationIncognito;
-}  // notification_builder
-
 // Provides a marshallable way for storing the information required to construct
 // a NSUSerNotification that is to be displayed on the system.
 //
@@ -47,6 +40,9 @@
 - (instancetype)initWithDictionary:(NSDictionary*)data;
 
 // Setters
+// Note for XPC users. Always use the setters from Chrome's main app. Do not
+// attempt to use them from XPC since some of the default strings and other
+// defaults are not available from the xpc service.
 - (void)setTitle:(NSString*)title;
 - (void)setSubTitle:(NSString*)subTitle;
 - (void)setContextMessage:(NSString*)contextMessage;
@@ -70,4 +66,4 @@
 
 @end
 
-#endif  // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_BUILDER_MAC_H_
+#endif  // CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_BUILDER_MAC_H_
diff --git a/chrome/browser/notifications/notification_builder_mac.mm b/chrome/browser/ui/cocoa/notifications/notification_builder_mac.mm
similarity index 68%
rename from chrome/browser/notifications/notification_builder_mac.mm
rename to chrome/browser/ui/cocoa/notifications/notification_builder_mac.mm
index 7a92e25..1d64752 100644
--- a/chrome/browser/notifications/notification_builder_mac.mm
+++ b/chrome/browser/ui/cocoa/notifications/notification_builder_mac.mm
@@ -2,12 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/notifications/notification_builder_mac.h"
+#import "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
 
 #import <AppKit/AppKit.h>
 
 #include "base/mac/mac_util.h"
 #include "base/mac/scoped_nsobject.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 
@@ -23,19 +24,11 @@
 NSString* const kNotificationButtonOne = @"buttonOne";
 NSString* const kNotificationButtonTwo = @"buttonTwo";
 NSString* const kNotificationTag = @"tag";
-
+NSString* const kNotificationCloseButtonTag = @"closeButton";
+NSString* const kNotificationOptionsButtonTag = @"optionsButton";
+NSString* const kNotificationSettingsButtonTag = @"settingsButton";
 }  // namespace
 
-namespace notification_builder {
-
-// Exposed constants to include user related data in the notification.
-NSString* const kNotificationOrigin = @"notificationOrigin";
-NSString* const kNotificationId = @"notificationId";
-NSString* const kNotificationProfileId = @"notificationProfileId";
-NSString* const kNotificationIncognito = @"notificationIncognito";
-
-}  // namespace notification_builder
-
 @implementation NotificationBuilder {
   base::scoped_nsobject<NSMutableDictionary> notificationData_;
 }
@@ -43,6 +36,15 @@
 - (instancetype)init {
   if ((self = [super init])) {
     notificationData_.reset([[NSMutableDictionary alloc] init]);
+    [notificationData_
+        setObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_CLOSE)
+           forKey:kNotificationCloseButtonTag];
+    [notificationData_
+        setObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_OPTIONS)
+           forKey:kNotificationOptionsButtonTag];
+    [notificationData_
+        setObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_SETTINGS)
+           forKey:kNotificationSettingsButtonTag];
   }
   return self;
 }
@@ -92,24 +94,24 @@
 - (void)setOrigin:(NSString*)origin {
   if (origin.length)
     [notificationData_ setObject:origin
-                          forKey:notification_builder::kNotificationOrigin];
+                          forKey:notification_constants::kNotificationOrigin];
 }
 
 - (void)setNotificationId:(NSString*)notificationId {
   DCHECK(notificationId.length);
   [notificationData_ setObject:notificationId
-                        forKey:notification_builder::kNotificationId];
+                        forKey:notification_constants::kNotificationId];
 }
 
 - (void)setProfileId:(NSString*)profileId {
   DCHECK(profileId.length);
   [notificationData_ setObject:profileId
-                        forKey:notification_builder::kNotificationProfileId];
+                        forKey:notification_constants::kNotificationProfileId];
 }
 
 - (void)setIncognito:(BOOL)incognito {
   [notificationData_ setObject:[NSNumber numberWithBool:incognito]
-                        forKey:notification_builder::kNotificationIncognito];
+                        forKey:notification_constants::kNotificationIncognito];
 }
 
 - (NSUserNotification*)buildUserNotification {
@@ -131,12 +133,16 @@
 
   // Buttons
   if ([toast respondsToSelector:@selector(_showsButtons)]) {
+    DCHECK([notificationData_ objectForKey:kNotificationCloseButtonTag]);
+    DCHECK([notificationData_ objectForKey:kNotificationSettingsButtonTag]);
+    DCHECK([notificationData_ objectForKey:kNotificationOptionsButtonTag]);
+
     [toast setValue:@YES forKey:@"_showsButtons"];
     // A default close button label is provided by the platform but we
     // explicitly override it in case the user decides to not
     // use the OS language in Chrome.
-    [toast setOtherButtonTitle:l10n_util::GetNSString(
-                                   IDS_NOTIFICATION_BUTTON_CLOSE)];
+    [toast setOtherButtonTitle:[notificationData_
+                                   objectForKey:kNotificationCloseButtonTag]];
 
     // Display the Settings button as the action button if there are either no
     // developer-provided action buttons, or the alternate action menu is not
@@ -144,8 +150,9 @@
     // TODO(miguelg): Extensions should not have a settings button.
     if (![notificationData_ objectForKey:kNotificationButtonOne] ||
         ![toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]) {
-      [toast setActionButtonTitle:l10n_util::GetNSString(
-                                      IDS_NOTIFICATION_BUTTON_SETTINGS)];
+      [toast
+          setActionButtonTitle:
+              [notificationData_ objectForKey:kNotificationSettingsButtonTag]];
     } else {
       // Otherwise show the alternate menu, then show the developer actions and
       // finally the settings one.
@@ -153,8 +160,9 @@
           [toast respondsToSelector:@selector(_alwaysShowAlternateActionMenu)]);
       DCHECK(
           [toast respondsToSelector:@selector(_alternateActionButtonTitles)]);
-      [toast setActionButtonTitle:l10n_util::GetNSString(
-                                      IDS_NOTIFICATION_BUTTON_OPTIONS)];
+      [toast
+          setActionButtonTitle:[notificationData_
+                                   objectForKey:kNotificationOptionsButtonTag]];
       [toast setValue:@YES forKey:@"_alwaysShowAlternateActionMenu"];
 
       NSMutableArray* buttons = [NSMutableArray arrayWithCapacity:3];
@@ -164,8 +172,8 @@
         [buttons
             addObject:[notificationData_ objectForKey:kNotificationButtonTwo]];
       }
-      [buttons
-          addObject:l10n_util::GetNSString(IDS_NOTIFICATION_BUTTON_SETTINGS)];
+      [buttons addObject:[notificationData_
+                             objectForKey:kNotificationSettingsButtonTag]];
       [toast setValue:buttons forKey:@"_alternateActionButtonTitles"];
     }
   }
@@ -178,30 +186,31 @@
   }
 
   NSString* origin =
-      [notificationData_ objectForKey:notification_builder::kNotificationOrigin]
+      [notificationData_
+          objectForKey:notification_constants::kNotificationOrigin]
           ? [notificationData_
-                objectForKey:notification_builder::kNotificationOrigin]
+                objectForKey:notification_constants::kNotificationOrigin]
           : @"";
   DCHECK(
-      [notificationData_ objectForKey:notification_builder::kNotificationId]);
+      [notificationData_ objectForKey:notification_constants::kNotificationId]);
   NSString* notificationId =
-      [notificationData_ objectForKey:notification_builder::kNotificationId];
+      [notificationData_ objectForKey:notification_constants::kNotificationId];
 
   DCHECK([notificationData_
-      objectForKey:notification_builder::kNotificationProfileId]);
+      objectForKey:notification_constants::kNotificationProfileId]);
   NSString* profileId = [notificationData_
-      objectForKey:notification_builder::kNotificationProfileId];
+      objectForKey:notification_constants::kNotificationProfileId];
 
   DCHECK([notificationData_
-      objectForKey:notification_builder::kNotificationIncognito]);
+      objectForKey:notification_constants::kNotificationIncognito]);
   NSNumber* incognito = [notificationData_
-      objectForKey:notification_builder::kNotificationIncognito];
+      objectForKey:notification_constants::kNotificationIncognito];
 
   toast.get().userInfo = @{
-    notification_builder::kNotificationOrigin : origin,
-    notification_builder::kNotificationId : notificationId,
-    notification_builder::kNotificationProfileId : profileId,
-    notification_builder::kNotificationIncognito : incognito,
+    notification_constants::kNotificationOrigin : origin,
+    notification_constants::kNotificationId : notificationId,
+    notification_constants::kNotificationProfileId : profileId,
+    notification_constants::kNotificationIncognito : incognito,
   };
 
   return toast.autorelease();
diff --git a/chrome/browser/notifications/notification_builder_mac_unittest.mm b/chrome/browser/ui/cocoa/notifications/notification_builder_mac_unittest.mm
similarity index 90%
rename from chrome/browser/notifications/notification_builder_mac_unittest.mm
rename to chrome/browser/ui/cocoa/notifications/notification_builder_mac_unittest.mm
index 910c41d..9baa9f55 100644
--- a/chrome/browser/notifications/notification_builder_mac_unittest.mm
+++ b/chrome/browser/ui/cocoa/notifications/notification_builder_mac_unittest.mm
@@ -7,7 +7,8 @@
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_nsobject.h"
 #include "base/strings/sys_string_conversions.h"
-#include "chrome/browser/notifications/notification_builder_mac.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(NotificationBuilderMacTest, TestNotificationNoButtons) {
@@ -47,7 +48,7 @@
   [builder setProfileId:@"profileId"];
   [builder setIncognito:false];
 
-   NSUserNotification* notification = [builder buildUserNotification];
+  NSUserNotification* notification = [builder buildUserNotification];
 
   EXPECT_EQ("Title", base::SysNSStringToUTF8([notification title]));
   EXPECT_EQ("SubTitle",
@@ -115,15 +116,15 @@
 
   EXPECT_EQ("https://www.miguel.com",
             base::SysNSStringToUTF8([userInfo
-                objectForKey:notification_builder::kNotificationOrigin]));
+                objectForKey:notification_constants::kNotificationOrigin]));
   EXPECT_EQ("Notification1",
-            base::SysNSStringToUTF8(
-                [userInfo objectForKey:notification_builder::kNotificationId]));
+            base::SysNSStringToUTF8([userInfo
+                objectForKey:notification_constants::kNotificationId]));
   EXPECT_EQ("Profile1",
             base::SysNSStringToUTF8([userInfo
-                objectForKey:notification_builder::kNotificationProfileId]));
+                objectForKey:notification_constants::kNotificationProfileId]));
   EXPECT_TRUE([[userInfo
-      objectForKey:notification_builder::kNotificationIncognito] boolValue]);
+      objectForKey:notification_constants::kNotificationIncognito] boolValue]);
 }
 
 TEST(NotificationBuilderMacTest, TestBuildDictionary) {
diff --git a/chrome/browser/ui/cocoa/notifications/notification_common.gyp b/chrome/browser/ui/cocoa/notifications/notification_common.gyp
new file mode 100644
index 0000000..cabb46f
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/notification_common.gyp
@@ -0,0 +1,29 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+'targets': [
+  {
+    # GN version: //chrome/browser/ui/notifications:common
+    'target_name': 'notification_common',
+    'type': 'static_library',
+      'include_dirs': [
+        '<(DEPTH)',
+      ],
+    'sources': [
+      'notification_builder_mac.h',
+      'notification_builder_mac.mm',
+      'notification_constants_mac.h',
+      'notification_constants_mac.mm',
+      'notification_response_builder_mac.h',
+      'notification_response_builder_mac.mm',
+    ],
+    'dependencies': [
+      '<(DEPTH)/base/base.gyp:base',
+      '<(DEPTH)/chrome/chrome_resources.gyp:chrome_strings',
+      '<(DEPTH)/ui/base/ui_base.gyp:ui_base',
+    ],
+  },
+],
+}
diff --git a/chrome/browser/ui/cocoa/notifications/notification_constants_mac.h b/chrome/browser/ui/cocoa/notifications/notification_constants_mac.h
new file mode 100644
index 0000000..e651130
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/notification_constants_mac.h
@@ -0,0 +1,22 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_CONSTANTS_MAC_H_
+#define CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_CONSTANTS_MAC_H_
+
+#import <Foundation/Foundation.h>
+
+namespace notification_constants {
+
+extern NSString* const kNotificationOrigin;
+extern NSString* const kNotificationId;
+extern NSString* const kNotificationProfileId;
+extern NSString* const kNotificationIncognito;
+
+extern NSString* const kNotificationOperation;
+extern NSString* const kNotificationButtonIndex;
+
+}  // notification_constants
+
+#endif  // CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_CONSTANTS_MAC_H_
diff --git a/chrome/browser/ui/cocoa/notifications/notification_constants_mac.mm b/chrome/browser/ui/cocoa/notifications/notification_constants_mac.mm
new file mode 100644
index 0000000..bd9dcfbb1
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/notification_constants_mac.mm
@@ -0,0 +1,19 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
+
+namespace notification_constants {
+
+// Applicable to NotificationBuilder and NotificationResponseBuilder
+NSString* const kNotificationOrigin = @"notificationOrigin";
+NSString* const kNotificationId = @"notificationId";
+NSString* const kNotificationProfileId = @"notificationProfileId";
+NSString* const kNotificationIncognito = @"notificationIncognito";
+
+// Only applicable to the NotificationResponseBuilder
+NSString* const kNotificationOperation = @"notificationOperation";
+NSString* const kNotificationButtonIndex = @"notificationButtonIndex";
+
+}  // notification_constants
diff --git a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h
new file mode 100644
index 0000000..4ed8bc3
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h
@@ -0,0 +1,20 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_RESPONSE_BUILDER_MAC_H_
+#define CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_RESPONSE_BUILDER_MAC_H_
+
+#import <Foundation/Foundation.h>
+
+@class NSUserNotification;
+
+// Provides a marshallable way for storing the information related to a
+// notification response action, clicking on it, clicking on a button etc.
+@interface NotificationResponseBuilder : NSObject
+
++ (NSDictionary*)buildDictionary:(NSUserNotification*)notification;
+
+@end
+
+#endif  // CHROME_BROWSER_UI_COCOA_NOTIFICATIONS_NOTIFICATION_RESPONSE_BUILDER_MAC_H_
diff --git a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm
new file mode 100644
index 0000000..cf4df0141
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.mm
@@ -0,0 +1,98 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h"
+
+#include "base/logging.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
+
+namespace {
+
+// Make sure this Obj-C enum is kept in sync with the
+// PlatformNotificationServiceImpl NotificationOperation enum.
+// The latter cannot be reused because the XPC service is not aware of
+// PlatformNotificationCenter.
+enum NotificationOperation {
+  NOTIFICATION_CLICK = 0,
+  NOTIFICATION_CLOSE = 1,
+  NOTIFICATION_SETTINGS = 2
+};
+}  // namespace
+
+@implementation NotificationResponseBuilder
+
++ (NSDictionary*)buildDictionary:(NSUserNotification*)notification {
+  NSString* origin =
+      [[notification userInfo]
+          objectForKey:notification_constants::kNotificationOrigin]
+          ? [[notification userInfo]
+                objectForKey:notification_constants::kNotificationOrigin]
+          : @"";
+  DCHECK([[notification userInfo]
+      objectForKey:notification_constants::kNotificationId]);
+  NSString* notificationId = [[notification userInfo]
+      objectForKey:notification_constants::kNotificationId];
+
+  DCHECK([[notification userInfo]
+      objectForKey:notification_constants::kNotificationProfileId]);
+  NSString* profileId = [[notification userInfo]
+      objectForKey:notification_constants::kNotificationProfileId];
+
+  DCHECK([[notification userInfo]
+      objectForKey:notification_constants::kNotificationIncognito]);
+  NSNumber* incognito = [[notification userInfo]
+      objectForKey:notification_constants::kNotificationIncognito];
+
+  // Initialize operation and button index for the case where the
+  // notification itself was clicked.
+  NotificationOperation operation = NOTIFICATION_CLICK;
+  int buttonIndex = -1;
+
+  // Determine whether the user clicked on a button, and if they did, whether it
+  // was a developer-provided button or the mandatory Settings button.
+  if (notification.activationType ==
+      NSUserNotificationActivationTypeActionButtonClicked) {
+    NSArray* alternateButtons = @[];
+    if ([notification
+            respondsToSelector:@selector(_alternateActionButtonTitles)]) {
+      alternateButtons =
+          [notification valueForKey:@"_alternateActionButtonTitles"];
+    }
+
+    bool multipleButtons = (alternateButtons.count > 0);
+
+    // No developer actions, just the settings button.
+    if (!multipleButtons) {
+      operation = NOTIFICATION_SETTINGS;
+      buttonIndex = -1;
+    } else {
+      // 0 based array containing.
+      // Button 1
+      // Button 2 (optional)
+      // Settings
+      NSNumber* actionIndex =
+          [notification valueForKey:@"_alternateActionIndex"];
+      operation = (actionIndex.unsignedLongValue == alternateButtons.count - 1)
+                      ? NOTIFICATION_SETTINGS
+                      : NOTIFICATION_CLICK;
+      buttonIndex =
+          (actionIndex.unsignedLongValue == alternateButtons.count - 1)
+              ? -1
+              : actionIndex.intValue;
+    }
+  }
+
+  return @{
+    notification_constants::kNotificationOrigin : origin,
+    notification_constants::kNotificationId : notificationId,
+    notification_constants::kNotificationProfileId : profileId,
+    notification_constants::kNotificationIncognito : incognito,
+    notification_constants::kNotificationOperation :
+        [NSNumber numberWithInt:operation],
+    notification_constants::
+    kNotificationButtonIndex : [NSNumber numberWithInt:buttonIndex],
+  };
+}
+
+@end
diff --git a/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm
new file mode 100644
index 0000000..0d4a78dc
--- /dev/null
+++ b/chrome/browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm
@@ -0,0 +1,175 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import <AppKit/AppKit.h>
+
+#include "base/mac/scoped_nsobject.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_builder_mac.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_constants_mac.h"
+#include "chrome/browser/ui/cocoa/notifications/notification_response_builder_mac.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(NotificationResponseBuilderMacTest, TestNotificationClick) {
+  base::scoped_nsobject<NotificationBuilder> builder(
+      [[NotificationBuilder alloc] init]);
+  [builder setTitle:@"Title"];
+  [builder setSubTitle:@"https://www.miguel.com"];
+  [builder setContextMessage:@""];
+  [builder setTag:@"tag1"];
+  [builder setIcon:[NSImage imageNamed:@"NSApplicationIcon"]];
+  [builder setNotificationId:@"notificationId"];
+  [builder setProfileId:@"profileId"];
+  [builder setIncognito:false];
+
+  NSUserNotification* notification = [builder buildUserNotification];
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDictionary:notification];
+
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+  EXPECT_EQ(0 /* NOTIFICATION_CLICK */, operation.intValue);
+  EXPECT_EQ(-1, buttonIndex.intValue);
+}
+
+TEST(NotificationResponseBuilderMacTest, TestNotificationSettingsClick) {
+  base::scoped_nsobject<NotificationBuilder> builder(
+      [[NotificationBuilder alloc] init]);
+  [builder setTitle:@"Title"];
+  [builder setSubTitle:@"https://www.miguel.com"];
+  [builder setContextMessage:@""];
+  [builder setTag:@"tag1"];
+  [builder setIcon:[NSImage imageNamed:@"NSApplicationIcon"]];
+  [builder setNotificationId:@"notificationId"];
+  [builder setProfileId:@"profileId"];
+  [builder setIncognito:false];
+
+  NSUserNotification* notification = [builder buildUserNotification];
+
+  // This will be set by the notification center to indicate the only available
+  // button was clicked.
+  [notification
+      setValue:
+          [NSNumber
+              numberWithInt:NSUserNotificationActivationTypeActionButtonClicked]
+        forKey:@"_activationType"];
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDictionary:notification];
+
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+  EXPECT_EQ(2 /* NOTIFICATION_SETTINGS */, operation.intValue);
+  EXPECT_EQ(-1, buttonIndex.intValue);
+}
+
+TEST(NotificationResponseBuilderMacTest, TestNotificationOneActionClick) {
+  base::scoped_nsobject<NotificationBuilder> builder(
+      [[NotificationBuilder alloc] init]);
+  [builder setTitle:@"Title"];
+  [builder setSubTitle:@"https://www.miguel.com"];
+  [builder setContextMessage:@""];
+  [builder setButtons:@"Button1" secondaryButton:@""];
+  [builder setTag:@"tag1"];
+  [builder setIcon:[NSImage imageNamed:@"NSApplicationIcon"]];
+  [builder setNotificationId:@"notificationId"];
+  [builder setProfileId:@"profileId"];
+  [builder setIncognito:false];
+
+  NSUserNotification* notification = [builder buildUserNotification];
+
+  // These values will be set by the notification center to indicate that button
+  // 1 was clicked.
+  [notification
+      setValue:
+          [NSNumber
+              numberWithInt:NSUserNotificationActivationTypeActionButtonClicked]
+        forKey:@"_activationType"];
+  [notification setValue:[NSNumber numberWithInt:0]
+                  forKey:@"_alternateActionIndex"];
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDictionary:notification];
+
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+  EXPECT_EQ(0 /* NOTIFICATION_CLICK */, operation.intValue);
+  EXPECT_EQ(0, buttonIndex.intValue);
+}
+
+TEST(NotificationResponseBuilderMacTest, TestNotificationTwoActionClick) {
+  base::scoped_nsobject<NotificationBuilder> builder(
+      [[NotificationBuilder alloc] init]);
+  [builder setTitle:@"Title"];
+  [builder setSubTitle:@"https://www.miguel.com"];
+  [builder setContextMessage:@""];
+  [builder setButtons:@"Button1" secondaryButton:@"Button2"];
+  [builder setTag:@"tag1"];
+  [builder setIcon:[NSImage imageNamed:@"NSApplicationIcon"]];
+  [builder setNotificationId:@"notificationId"];
+  [builder setProfileId:@"profileId"];
+  [builder setIncognito:false];
+
+  NSUserNotification* notification = [builder buildUserNotification];
+
+  // These values will be set by the notification center to indicate that button
+  // 2 was clicked.
+  [notification
+      setValue:
+          [NSNumber
+              numberWithInt:NSUserNotificationActivationTypeActionButtonClicked]
+        forKey:@"_activationType"];
+  [notification setValue:[NSNumber numberWithInt:1]
+                  forKey:@"_alternateActionIndex"];
+
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDictionary:notification];
+
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+  EXPECT_EQ(0 /* NOTIFICATION_CLICK */, operation.intValue);
+  EXPECT_EQ(1, buttonIndex.intValue);
+}
+
+TEST(NotificationResponseBuilderMacTest,
+     TestNotificationTwoActionSettingsClick) {
+  base::scoped_nsobject<NotificationBuilder> builder(
+      [[NotificationBuilder alloc] init]);
+  [builder setTitle:@"Title"];
+  [builder setSubTitle:@"https://www.miguel.com"];
+  [builder setContextMessage:@""];
+  [builder setButtons:@"Button1" secondaryButton:@"Button2"];
+  [builder setTag:@"tag1"];
+  [builder setIcon:[NSImage imageNamed:@"NSApplicationIcon"]];
+  [builder setNotificationId:@"notificationId"];
+  [builder setProfileId:@"profileId"];
+  [builder setIncognito:false];
+
+  NSUserNotification* notification = [builder buildUserNotification];
+
+  // These values will be set by the notification center to indicate that button
+  // 2 was clicked.
+  [notification
+      setValue:
+          [NSNumber
+              numberWithInt:NSUserNotificationActivationTypeActionButtonClicked]
+        forKey:@"_activationType"];
+  [notification setValue:[NSNumber numberWithInt:2]
+                  forKey:@"_alternateActionIndex"];
+
+  NSDictionary* response =
+      [NotificationResponseBuilder buildDictionary:notification];
+
+  NSNumber* operation =
+      [response objectForKey:notification_constants::kNotificationOperation];
+  NSNumber* buttonIndex =
+      [response objectForKey:notification_constants::kNotificationButtonIndex];
+  EXPECT_EQ(2 /* NOTIFICATION_SETTINGS */, operation.intValue);
+  EXPECT_EQ(-1, buttonIndex.intValue);
+}
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc b/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
index c1e1a835..a0e22ff 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
@@ -257,24 +257,23 @@
       }
       break;
     case GTK_DELETE_DISPLAY_LINES:
-      commands[0] = TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_LINE;
+      commands[0] = TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_LINE;
       commands[1] = TextEditCommandAuraLinux::DELETE_TO_END_OF_LINE;
       break;
     case GTK_DELETE_DISPLAY_LINE_ENDS:
-      commands[0] = (count > 0 ?
-          TextEditCommandAuraLinux::DELETE_TO_END_OF_LINE :
-          TextEditCommandAuraLinux::DELETE_TO_BEGINING_OF_LINE);
+      commands[0] =
+          (count > 0 ? TextEditCommandAuraLinux::DELETE_TO_END_OF_LINE
+                     : TextEditCommandAuraLinux::DELETE_TO_BEGINNING_OF_LINE);
       break;
     case GTK_DELETE_PARAGRAPH_ENDS:
-      commands[0] = (count > 0 ?
-          TextEditCommandAuraLinux::DELETE_TO_END_OF_PARAGRAPH :
-          TextEditCommandAuraLinux::DELETE_TO_BEGINING_OF_PARAGRAPH);
+      commands[0] =
+          (count > 0
+               ? TextEditCommandAuraLinux::DELETE_TO_END_OF_PARAGRAPH
+               : TextEditCommandAuraLinux::DELETE_TO_BEGINNING_OF_PARAGRAPH);
       break;
     case GTK_DELETE_PARAGRAPHS:
-      commands[0] =
-          TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_PARAGRAPH;
-      commands[1] =
-          TextEditCommandAuraLinux::DELETE_TO_END_OF_PARAGRAPH;
+      commands[0] = TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_PARAGRAPH;
+      commands[1] = TextEditCommandAuraLinux::DELETE_TO_END_OF_PARAGRAPH;
       break;
     default:
       // GTK_DELETE_WHITESPACE has no corresponding editor command.
@@ -327,22 +326,24 @@
                  TextEditCommandAuraLinux::MOVE_UP);
       break;
     case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
-      command = (count > 0 ?
-                 TextEditCommandAuraLinux::MOVE_TO_END_OF_LINE :
-                 TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_LINE);
+      command =
+          (count > 0 ? TextEditCommandAuraLinux::MOVE_TO_END_OF_LINE
+                     : TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_LINE);
       break;
     case GTK_MOVEMENT_PARAGRAPH_ENDS:
-      command = (count > 0 ?
-                 TextEditCommandAuraLinux::MOVE_TO_END_OF_PARAGRAPH :
-                 TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_PARAGRAPH);
+      command =
+          (count > 0
+               ? TextEditCommandAuraLinux::MOVE_TO_END_OF_PARAGRAPH
+               : TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_PARAGRAPH);
       break;
     case GTK_MOVEMENT_PAGES:
       command = (count > 0 ? TextEditCommandAuraLinux::MOVE_PAGE_DOWN :
                  TextEditCommandAuraLinux::MOVE_PAGE_UP);
       break;
     case GTK_MOVEMENT_BUFFER_ENDS:
-      command = (count > 0 ? TextEditCommandAuraLinux::MOVE_TO_END_OF_DOCUMENT :
-                 TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_DOCUMENT);
+      command =
+          (count > 0 ? TextEditCommandAuraLinux::MOVE_TO_END_OF_DOCUMENT
+                     : TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_DOCUMENT);
       break;
     default:
       // GTK_MOVEMENT_PARAGRAPHS and GTK_MOVEMENT_HORIZONTAL_PAGES have
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h b/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h
index 32584d4..c8668911 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h
+++ b/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/event_types.h"
-#include "ui/events/linux/text_edit_command_auralinux.h"
+#include "ui/base/ime/linux/text_edit_command_auralinux.h"
 
 namespace content {
 struct NativeWebKeyboardEvent;
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.h b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
index 72080a7..cd5d8af 100644
--- a/chrome/browser/ui/libgtk2ui/gtk2_ui.h
+++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.h
@@ -14,7 +14,7 @@
 #include "base/observer_list.h"
 #include "chrome/browser/ui/libgtk2ui/gtk2_signal.h"
 #include "chrome/browser/ui/libgtk2ui/libgtk2ui_export.h"
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/views/linux_ui/linux_ui.h"
 #include "ui/views/window/frame_buttons.h"
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index 7a51417d..4a0969d 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -28,6 +28,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/chromium_strings.h"
 #include "chrome/grit/generated_resources.h"
+#include "chrome/grit/settings_strings.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/signin/core/browser/signin_manager.h"
@@ -107,16 +108,30 @@
           GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
     const gfx::Image* icon = entry->GetGAIAPicture();
     if (icon) {
+      std::unique_ptr<base::DictionaryValue> gaia_picture_info(
+          new base::DictionaryValue());
       gfx::Image icon2 = profiles::GetAvatarIconForWebUI(*icon, true);
       gaia_picture_url_ = webui::GetBitmapDataUrl(icon2.AsBitmap());
-      image_url_list->AppendString(gaia_picture_url_);
+      gaia_picture_info->SetString("url", gaia_picture_url_);
+      gaia_picture_info->SetString(
+          "label",
+          l10n_util::GetStringUTF16(IDS_SETTINGS_CHANGE_PICTURE_PROFILE_PHOTO));
+      image_url_list->Append(std::move(gaia_picture_info));
     }
   }
 
   // Next add the default avatar icons and names.
-  for (size_t i = 0; i < profiles::GetDefaultAvatarIconCount(); i++) {
-    std::string url = profiles::GetDefaultAvatarIconUrl(i);
-    image_url_list->AppendString(url);
+  size_t placeholder_avatar_index = profiles::GetPlaceholderAvatarIndex();
+  for (size_t i = 0; i < profiles::GetDefaultAvatarIconCount() &&
+                     i != placeholder_avatar_index;
+       i++) {
+    std::unique_ptr<base::DictionaryValue> avatar_info(
+        new base::DictionaryValue());
+    avatar_info->SetString("url", profiles::GetDefaultAvatarIconUrl(i));
+    avatar_info->SetString(
+        "label", l10n_util::GetStringUTF16(
+                     profiles::GetDefaultAvatarLabelResourceIDAtIndex(i)));
+    image_url_list->Append(std::move(avatar_info));
   }
 
   return image_url_list;
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
index 6c8a505..01362e6f 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler_unittest.cc
@@ -46,15 +46,21 @@
   }
 
   void VerifyIconList(const base::Value* value) {
-    const base::ListValue* icon_urls = nullptr;
-    ASSERT_TRUE(value->GetAsList(&icon_urls));
+    const base::ListValue* icons = nullptr;
+    ASSERT_TRUE(value->GetAsList(&icons));
 
-    // Expect the list of icon URLs to be a non-empty list of non-empty strings.
-    EXPECT_FALSE(icon_urls->empty());
-    for (size_t i = 0; i < icon_urls->GetSize(); ++i) {
+    // Expect a non-empty list of dictionaries containing non-empty strings for
+    // profile avatar icon urls and labels.
+    EXPECT_FALSE(icons->empty());
+    for (size_t i = 0; i < icons->GetSize(); ++i) {
+      const base::DictionaryValue* icon = nullptr;
+      EXPECT_TRUE(icons->GetDictionary(i, &icon));
       std::string icon_url;
-      EXPECT_TRUE(icon_urls->GetString(i, &icon_url));
+      EXPECT_TRUE(icon->GetString("url", &icon_url));
       EXPECT_FALSE(icon_url.empty());
+      std::string icon_label;
+      EXPECT_TRUE(icon->GetString("label", &icon_label));
+      EXPECT_FALSE(icon_label.empty());
     }
   }
 
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 1793f5f..bfda9df 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -177,6 +177,8 @@
       'browser/component_updater/recovery_component_installer.h',
       'browser/component_updater/sth_set_component_installer.cc',
       'browser/component_updater/sth_set_component_installer.h',
+      'browser/component_updater/subresource_filter_component_installer.cc',
+      'browser/component_updater/subresource_filter_component_installer.h',
       'browser/component_updater/supervised_user_whitelist_installer.cc',
       'browser/component_updater/supervised_user_whitelist_installer.h',
       'browser/component_updater/sw_reporter_installer_win.cc',
@@ -2201,8 +2203,6 @@
       'browser/notifications/native_notification_display_service.h',
       'browser/notifications/notification.cc',
       'browser/notifications/notification.h',
-      'browser/notifications/notification_builder_mac.mm',
-      'browser/notifications/notification_builder_mac.h',
       'browser/notifications/notification_delegate.h',
       'browser/notifications/notification_display_service.h',
       'browser/notifications/notification_display_service_factory.cc',
@@ -3748,6 +3748,11 @@
                 '<@(chrome_browser_notifications_android_java_ui_sources)',
               ],
             }],
+            ['OS=="mac"', {
+              'dependencies' : [
+                'browser/ui/cocoa/notifications/notification_common.gyp:notification_common',
+              ],
+            }],
           ],
         }],
         ['enable_themes==1', {
diff --git a/chrome/chrome_dll_bundle.gypi b/chrome/chrome_dll_bundle.gypi
index bbcc1d2..5b49c21 100644
--- a/chrome/chrome_dll_bundle.gypi
+++ b/chrome/chrome_dll_bundle.gypi
@@ -129,6 +129,7 @@
         ['branding == "Chrome"', {
           'files': [
             '<(PRODUCT_DIR)/PepperFlash/PepperFlashPlayer.plugin',
+            '<(PRODUCT_DIR)/PepperFlash/manifest.json',
           ],
         }],
       ],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index a1e757e..b65eec4 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -69,6 +69,7 @@
       'browser/command_updater_unittest.cc',
       'browser/component_updater/chrome_component_updater_configurator_unittest.cc',
       'browser/component_updater/sth_set_component_installer_unittest.cc',
+      'browser/component_updater/subresource_filter_component_installer_unittest.cc',
       'browser/component_updater/supervised_user_whitelist_installer_unittest.cc',
       'browser/content_settings/content_settings_default_provider_unittest.cc',
       'browser/content_settings/content_settings_mock_observer.cc',
@@ -561,7 +562,6 @@
       'browser/media/cast_transport_host_filter_unittest.cc',
       'browser/metrics/extensions_metrics_provider_unittest.cc',
       'browser/notifications/extension_welcome_notification_unittest.cc',
-      'browser/notifications/notification_builder_mac_unittest.mm',
       'browser/notifications/notification_conversion_helper_unittest.cc',
       'browser/renderer_context_menu/context_menu_content_type_unittest.cc',
       'browser/search/hotword_service_unittest.cc',
@@ -1273,6 +1273,8 @@
       'browser/ui/cocoa/location_bar/zoom_decoration_unittest.mm',
       'browser/ui/cocoa/media_picker/desktop_media_picker_controller_unittest.mm',
       'browser/ui/cocoa/menu_button_unittest.mm',
+      'browser/ui/cocoa/notifications/notification_builder_mac_unittest.mm',
+      'browser/ui/cocoa/notifications/notification_response_builder_mac_unittest.mm',
       'browser/ui/cocoa/nsmenuitem_additions_unittest.mm',
       'browser/ui/cocoa/omnibox/omnibox_popup_cell_unittest.mm',
       'browser/ui/cocoa/omnibox/omnibox_popup_matrix_unittest.mm',
diff --git a/chrome/common/crash_keys.cc b/chrome/common/crash_keys.cc
index 65e96a4..864c4e2 100644
--- a/chrome/common/crash_keys.cc
+++ b/chrome/common/crash_keys.cc
@@ -118,6 +118,7 @@
 #endif
 
     // content/:
+    { "bad_message_reason", kSmallSize },
     { "discardable-memory-allocated", kSmallSize },
     { "discardable-memory-free", kSmallSize },
     { kFontKeyName, kSmallSize},
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index 1531b23..7ae881f 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -2329,6 +2329,33 @@
   EXPECT_TRUE(form.fields[2].should_autocomplete);
 }
 
+// Tests CSS classes are set.
+TEST_F(FormAutofillTest, WebFormElementToFormData_CssClasses) {
+  LoadHTML(
+      "<FORM name='TestForm' id='form' action='http://cnn.com' method='post' "
+      "autocomplete='off'>"
+      "    <INPUT type='text' id='firstname' class='firstname_field' />"
+      "    <INPUT type='text' id='lastname' class='lastname_field' />"
+      "    <INPUT type='text' id='addressline1'  />"
+      "</FORM>");
+
+  WebFrame* frame = GetMainFrame();
+  ASSERT_NE(nullptr, frame);
+
+  WebFormElement web_form =
+      frame->document().getElementById("form").to<WebFormElement>();
+  ASSERT_FALSE(web_form.isNull());
+
+  FormData form;
+  EXPECT_TRUE(WebFormElementToFormData(web_form, WebFormControlElement(),
+                                       EXTRACT_NONE, &form, nullptr));
+
+  EXPECT_EQ(3U, form.fields.size());
+  EXPECT_EQ(ASCIIToUTF16("firstname_field"), form.fields[0].css_classes);
+  EXPECT_EQ(ASCIIToUTF16("lastname_field"), form.fields[1].css_classes);
+  EXPECT_EQ(base::string16(), form.fields[2].css_classes);
+}
+
 TEST_F(FormAutofillTest, ExtractForms) {
   ExpectJohnSmithLabels(
       "<FORM name='TestForm' action='http://cnn.com' method='post'>"
diff --git a/chrome/renderer/autofill/password_generation_agent_browsertest.cc b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
index 2743a9a..d376f05 100644
--- a/chrome/renderer/autofill/password_generation_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_generation_agent_browsertest.cc
@@ -72,16 +72,27 @@
     render_thread_->sink().ClearMessages();
   }
 
+  void AllowToRunFormClassifier() {
+    AutofillMsg_AllowToRunFormClassifier msg(0);
+    static_cast<IPC::Listener*>(password_generation_)->OnMessageReceived(msg);
+  }
+
   void ExpectFormClassifierVoteReceived(
+      bool received,
       const base::string16& expected_generation_element) {
     const IPC::Message* message =
         render_thread_->sink().GetFirstMessageMatching(
             AutofillHostMsg_SaveGenerationFieldDetectedByClassifier::ID);
-    ASSERT_TRUE(message);
-    std::tuple<autofill::PasswordForm, base::string16> actual_parameters;
-    AutofillHostMsg_SaveGenerationFieldDetectedByClassifier::Read(
-        message, &actual_parameters);
-    EXPECT_EQ(expected_generation_element, std::get<1>(actual_parameters));
+    if (received) {
+      ASSERT_TRUE(message);
+      std::tuple<autofill::PasswordForm, base::string16> actual_parameters;
+      AutofillHostMsg_SaveGenerationFieldDetectedByClassifier::Read(
+          message, &actual_parameters);
+      EXPECT_EQ(expected_generation_element, std::get<1>(actual_parameters));
+    } else {
+      ASSERT_FALSE(message);
+    }
+
     render_thread_->sink().ClearMessages();
   }
 
@@ -661,13 +672,23 @@
 }
 
 TEST_F(PasswordGenerationAgentTest, FormClassifierVotesSignupForm) {
+  AllowToRunFormClassifier();
   LoadHTMLWithUserGesture(kAccountCreationFormHTML);
-  ExpectFormClassifierVoteReceived(base::ASCIIToUTF16("first_password"));
+  ExpectFormClassifierVoteReceived(true /* vote is expected */,
+                                   base::ASCIIToUTF16("first_password"));
 }
 
 TEST_F(PasswordGenerationAgentTest, FormClassifierVotesSigninForm) {
+  AllowToRunFormClassifier();
   LoadHTMLWithUserGesture(kSigninFormHTML);
-  ExpectFormClassifierVoteReceived(base::string16());
+  ExpectFormClassifierVoteReceived(true /* vote is expected */,
+                                   base::string16());
+}
+
+TEST_F(PasswordGenerationAgentTest, FormClassifierDisabled) {
+  LoadHTMLWithUserGesture(kSigninFormHTML);
+  ExpectFormClassifierVoteReceived(false /* vote is not expected */,
+                                   base::string16());
 }
 
 }  // namespace autofill
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index c0a4a7f..7aaa5f2 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -76,6 +76,7 @@
 #include "components/plugins/renderer/mobile_youtube_plugin.h"
 #include "components/signin/core/common/profile_management_switches.h"
 #include "components/startup_metric_utils/common/startup_metric.mojom.h"
+#include "components/subresource_filter/content/renderer/ruleset_dealer.h"
 #include "components/subresource_filter/content/renderer/subresource_filter_agent.h"
 #include "components/version_info/version_info.h"
 #include "components/visitedlink/renderer/visitedlink_slave.h"
@@ -357,6 +358,8 @@
   phishing_classifier_.reset(safe_browsing::PhishingClassifierFilter::Create());
 #endif
   prerender_dispatcher_.reset(new prerender::PrerenderDispatcher());
+  subresource_filter_ruleset_dealer_.reset(
+      new subresource_filter::RulesetDealer());
 #if defined(ENABLE_WEBRTC)
   webrtc_logging_message_filter_ = new WebRtcLoggingMessageFilter(
       thread->GetIOMessageLoopProxy());
@@ -368,6 +371,7 @@
 #endif
   thread->AddObserver(visited_link_slave_.get());
   thread->AddObserver(prerender_dispatcher_.get());
+  thread->AddObserver(subresource_filter_ruleset_dealer_.get());
   thread->AddObserver(SearchBouncer::GetInstance());
 
 #if defined(ENABLE_WEBRTC)
@@ -509,7 +513,8 @@
   new AutofillAgent(render_frame, password_autofill_agent,
                     password_generation_agent);
 
-  new subresource_filter::SubresourceFilterAgent(render_frame);
+  new subresource_filter::SubresourceFilterAgent(
+      render_frame, subresource_filter_ruleset_dealer_.get());
 }
 
 void ChromeContentRendererClient::RenderViewCreated(
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 2168ad7e..56a5b241 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -54,6 +54,10 @@
 class PhishingClassifierFilter;
 }
 
+namespace subresource_filter {
+class RulesetDealer;
+}
+
 namespace visitedlink {
 class VisitedLinkSlave;
 }
@@ -211,6 +215,8 @@
 #endif
   std::unique_ptr<visitedlink::VisitedLinkSlave> visited_link_slave_;
   std::unique_ptr<safe_browsing::PhishingClassifierFilter> phishing_classifier_;
+  std::unique_ptr<subresource_filter::RulesetDealer>
+      subresource_filter_ruleset_dealer_;
   std::unique_ptr<prerender::PrerenderDispatcher> prerender_dispatcher_;
 #if defined(ENABLE_WEBRTC)
   scoped_refptr<WebRtcLoggingMessageFilter> webrtc_logging_message_filter_;
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
index 6596427a..4e13fcd 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -22,18 +22,12 @@
   __proto__: PolymerTest.prototype,
 
   /** @override */
-  extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([
-    'cr_slider_tests.js',
-    'cr_toolbar_search_field_tests.js',
-  ]),
+  extraLibraries: PolymerTest.getLibraries(ROOT_PATH),
 
-  /**
-   * Hack: load a page underneath chrome://resources so script errors come
-   * from the same "domain" and can be viewed. HTML imports aren't deduped with
-   * the current page, but it should be safe to load assert.html twice.
-   * @override
-   */
-  browsePreload: 'chrome://resources/html/assert.html',
+  /** @override */
+  get browsePreload() {
+    throw 'this is abstract and should be overriden by subclasses';
+  },
 
   /** @override */
   setUp: function() {
@@ -43,12 +37,62 @@
   },
 };
 
-TEST_F('CrElementsBrowserTest', 'CrToolbarSearchFieldTest', function() {
+function CrElementsProfileAvatarSelectorTest() {}
+
+CrElementsProfileAvatarSelectorTest.prototype = {
+  __proto__: CrElementsBrowserTest.prototype,
+
+  /** @override */
+  browsePreload:
+      'chrome://resources/cr_elements/cr_profile_avatar_selector/' +
+      'cr_profile_avatar_selector.html',
+
+  /** @override */
+  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    'cr_profile_avatar_selector_tests.js',
+  ]),
+};
+
+TEST_F('CrElementsProfileAvatarSelectorTest', 'All', function() {
+  cr_profile_avatar_selector.registerTests();
+  mocha.run();
+});
+
+function CrElementsToolbarSearchFieldTest() {}
+
+CrElementsToolbarSearchFieldTest.prototype = {
+  __proto__: CrElementsBrowserTest.prototype,
+
+  /** @override */
+  browsePreload:
+      'chrome://resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html',
+
+  /** @override */
+  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    'cr_toolbar_search_field_tests.js',
+  ]),
+};
+
+TEST_F('CrElementsToolbarSearchFieldTest', 'All', function() {
   cr_toolbar_search_field.registerTests();
   mocha.run();
 });
 
-TEST_F('CrElementsBrowserTest', 'CrSliderTest', function() {
+function CrElementsSliderTest() {}
+
+CrElementsSliderTest.prototype = {
+  __proto__: CrElementsBrowserTest.prototype,
+
+  /** @override */
+  browsePreload: 'chrome://resources/cr_elements/cr_slider/cr_slider.html',
+
+  /** @override */
+  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    'cr_slider_tests.js',
+  ]),
+};
+
+TEST_F('CrElementsSliderTest', 'All', function() {
   cr_slider.registerTests();
   mocha.run();
 });
diff --git a/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js b/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
new file mode 100644
index 0000000..61ae163
--- /dev/null
+++ b/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.js
@@ -0,0 +1,97 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** @fileoverview Suite of tests for cr-profile-avatar-selector. */
+cr.define('cr_profile_avatar_selector', function() {
+  function registerTests() {
+    suite('cr-profile-avatar-selector', function() {
+      /** @type {CrProfileAvatarSelectorElement} */
+      var avatarSelector = null;
+
+      /** @return {CrProfileAvatarSelectorElement} */
+      function createElement() {
+        var avatarSelector =
+            document.createElement('cr-profile-avatar-selector');
+        avatarSelector.avatars =
+            [{url: 'chrome://avatar1.png', label: 'avatar1'},
+             {url: 'chrome://avatar2.png', label: 'avatar2'},
+             {url: 'chrome://avatar3.png', label: 'avatar3'}];
+        return avatarSelector;
+      }
+
+      setup(function() {
+        avatarSelector = createElement();
+        document.body.appendChild(avatarSelector);
+        Polymer.dom.flush();
+      });
+
+      teardown(function() {
+        avatarSelector.remove();
+      });
+
+      test('Displays avatars', function() {
+        assertEquals(3, avatarSelector.$.selector.items.length);
+      });
+
+      test('Can update avatars', function() {
+        avatarSelector.pop('avatars');
+        Polymer.dom.flush();
+        assertEquals(2, avatarSelector.$.selector.items.length);
+      });
+
+      test('No avatar is initially selected', function() {
+        var selector = avatarSelector.$.selector;
+
+        assertFalse(!!avatarSelector.selectedAvatarUrl);
+        assertFalse(selector.items[0].classList.contains('iron-selected'));
+        assertFalse(selector.items[1].classList.contains('iron-selected'));
+        assertFalse(selector.items[2].classList.contains('iron-selected'));
+      });
+
+      test('An avatar is initially selected if selectedAvatarUrl is set',
+           function() {
+        var anotherAvatarSelector = createElement();
+        anotherAvatarSelector.selectedAvatarUrl =
+            anotherAvatarSelector.avatars[0].url;
+        document.body.appendChild(anotherAvatarSelector);
+        Polymer.dom.flush();
+
+        var selector = anotherAvatarSelector.$.selector;
+
+        assertEquals('chrome://avatar1.png',
+                     anotherAvatarSelector.selectedAvatarUrl);
+        assertTrue(selector.items[0].classList.contains('iron-selected'));
+        assertFalse(selector.items[1].classList.contains('iron-selected'));
+        assertFalse(selector.items[2].classList.contains('iron-selected'));
+      });
+
+      test('Can select avatar', function() {
+        var selector = avatarSelector.$.selector;
+
+        // Simulate tapping the third avatar.
+        MockInteractions.tap(selector.items[2]);
+        assertEquals('chrome://avatar3.png', avatarSelector.selectedAvatarUrl);
+        assertFalse(selector.items[0].classList.contains('iron-selected'));
+        assertFalse(selector.items[1].classList.contains('iron-selected'));
+        assertTrue(selector.items[2].classList.contains('iron-selected'));
+      });
+
+      test('Fires iron-activate event when an avatar is activated',
+           function(done) {
+        avatarSelector.addEventListener('iron-activate',
+                                        function(event) {
+          assertEquals(event.detail.selected, 'chrome://avatar2.png');
+          done();
+        });
+
+        // Simulate tapping the second avatar.
+        MockInteractions.tap(avatarSelector.$.selector.items[1]);
+      });
+    });
+  }
+
+  return {
+    registerTests: registerTests,
+  };
+});
diff --git a/chrome/test/data/webui/cr_elements/cr_slider_tests.js b/chrome/test/data/webui/cr_elements/cr_slider_tests.js
index 3beaeae..5147c26 100644
--- a/chrome/test/data/webui/cr_elements/cr_slider_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_slider_tests.js
@@ -17,11 +17,6 @@
 
       var tickValues = [2, 4, 8, 16, 32, 64, 128];
 
-      suiteSetup(function() {
-        return PolymerTest.importHtml(
-            'chrome://resources/cr_elements/cr_slider/cr_slider.html');
-      });
-
       setup(function() {
         PolymerTest.clearBody();
         slider = document.createElement('cr-slider');
diff --git a/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js b/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js
index 257e35c..268cfa7 100644
--- a/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.js
@@ -18,12 +18,6 @@
         field.onSearchTermSearch();
       }
 
-      suiteSetup(function() {
-        return PolymerTest.importHtml(
-            'chrome://resources/cr_elements/cr_toolbar/' +
-            'cr_toolbar_search_field.html');
-      });
-
       setup(function() {
         PolymerTest.clearBody();
         field = document.createElement('cr-toolbar-search-field');
diff --git a/chrome/test/data/webui/settings/people_page_manage_profile_test.js b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
index ba0b3a74..432b448c 100644
--- a/chrome/test/data/webui/settings/people_page_manage_profile_test.js
+++ b/chrome/test/data/webui/settings/people_page_manage_profile_test.js
@@ -21,7 +21,8 @@
     /** @override */
     getAvailableIcons: function() {
       this.methodCalled('getAvailableIcons');
-      return Promise.resolve(['fake-icon-1.png', 'fake-icon-2.png']);
+      return Promise.resolve([{url: 'fake-icon-1.png', label: 'fake-icon-1'},
+                              {url: 'fake-icon-2.png', label: 'fake-icon-2'}]);
     },
 
     /** @override */
@@ -52,13 +53,13 @@
       //  - has the correct icon selected
       //  - can select a new icon
       test('ManageProfileChangeIcon', function() {
-        var selector = manageProfile.$.selector;
+        var selector = manageProfile.$.selector.$.selector;
         assertTrue(!!selector);
 
         return browserProxy.whenCalled('getAvailableIcons').then(function() {
           Polymer.dom.flush();
 
-          assertEquals('fake-icon-1.png', selector.selected);
+          assertEquals('fake-icon-1.png', manageProfile.profileIconUrl);
           assertEquals(2, selector.items.length);
           assertTrue(selector.items[0].classList.contains('iron-selected'));
           assertFalse(selector.items[1].classList.contains('iron-selected'));
@@ -74,7 +75,7 @@
 
       // Tests profile icon updates pushed from the browser.
       test('ManageProfileIconUpdated', function() {
-        var selector = manageProfile.$.selector;
+        var selector = manageProfile.$.selector.$.selector;
         assertTrue(!!selector);
 
         return browserProxy.whenCalled('getAvailableIcons').then(function() {
@@ -82,7 +83,7 @@
 
           Polymer.dom.flush();
 
-          assertEquals('fake-icon-2.png', selector.selected);
+          assertEquals('fake-icon-2.png', manageProfile.profileIconUrl);
           assertEquals(2, selector.items.length);
           assertFalse(selector.items[0].classList.contains('iron-selected'));
           assertTrue(selector.items[1].classList.contains('iron-selected'));
diff --git a/chromecast/common/media/OWNERS b/chromecast/common/media/OWNERS
index 24bcf83b..cbf806a 100644
--- a/chromecast/common/media/OWNERS
+++ b/chromecast/common/media/OWNERS
@@ -1,5 +1,5 @@
-per-file *_message*.h=set noparent
-per-file *_message*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
 
 per-file *_messages.cc=set noparent
 per-file *_messages.cc=file://ipc/SECURITY_OWNERS
diff --git a/components/BUILD.gn b/components/BUILD.gn
index bfc7882..b8f705d4 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -186,6 +186,7 @@
       "//components/invalidation/impl:unit_tests",
       "//components/keyed_service/content:unit_tests",
       "//components/link_header_util:unit_tests",
+      "//components/memory_coordinator/child:unit_tests",
       "//components/navigation_interception:unit_tests",
       "//components/network_hints/renderer:unit_tests",
       "//components/ntp_tiles:unit_tests",
@@ -198,6 +199,7 @@
       "//components/safe_browsing_db:unit_tests",
       "//components/safe_json:unit_tests",
       "//components/scheduler:unit_tests",
+      "//components/subresource_filter/content/browser:unit_tests",
       "//components/test_runner:test_runner",
       "//components/tracing:unit_tests",
       "//components/visitedlink/test:unit_tests",
diff --git a/components/OWNERS b/components/OWNERS
index 16a2078..3183d68 100644
--- a/components/OWNERS
+++ b/components/OWNERS
@@ -106,6 +106,7 @@
 
 per-file login.gypi=file://components/login/OWNERS
 
+per-file memory_coordinator.gypi=file://components/memory_coordinator/OWNERS
 per-file memory_pressure.gypi=file://components/memory_pressure/OWNERS
 
 per-file metrics.gypi=file://components/metrics/OWNERS
diff --git a/components/autofill/content/common/OWNERS b/components/autofill/content/common/OWNERS
index f133b34e..9fbdf6f 100644
--- a/components/autofill/content/common/OWNERS
+++ b/components/autofill/content/common/OWNERS
@@ -1,4 +1,4 @@
 # Changes to IPC messages require a security review to avoid introducing
 # new sandbox escapes.
-per-file *messages*.h=set noparent
-per-file *messages*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/components/autofill/content/common/autofill_messages.h b/components/autofill/content/common/autofill_messages.h
index 09f446a..e084879 100644
--- a/components/autofill/content/common/autofill_messages.h
+++ b/components/autofill/content/common/autofill_messages.h
@@ -168,6 +168,9 @@
 IPC_MESSAGE_ROUTED1(AutofillMsg_GeneratedPasswordAccepted,
                     base::string16 /* generated_password */)
 
+// Tells the renderer to enable the form classifier.
+IPC_MESSAGE_ROUTED0(AutofillMsg_AllowToRunFormClassifier)
+
 // Tells the renderer to fill the username and password with with given
 // values.
 IPC_MESSAGE_ROUTED2(AutofillMsg_FillPasswordSuggestion,
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index c2e6030..69e24c1c 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1366,6 +1366,7 @@
   CR_DEFINE_STATIC_LOCAL(WebString, kAutocomplete, ("autocomplete"));
   CR_DEFINE_STATIC_LOCAL(WebString, kRole, ("role"));
   CR_DEFINE_STATIC_LOCAL(WebString, kPlaceholder, ("placeholder"));
+  CR_DEFINE_STATIC_LOCAL(WebString, kClass, ("class"));
 
   // The label is not officially part of a WebFormControlElement; however, the
   // labels for all form control elements are scraped from the DOM and set in
@@ -1384,6 +1385,8 @@
     field->role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
 
   field->placeholder = element.getAttribute(kPlaceholder);
+  if (element.hasAttribute(kClass))
+    field->css_classes = element.getAttribute(kClass);
 
   if (!IsAutofillableElement(element))
     return;
diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc
index 0aee606..1264b0c 100644
--- a/components/autofill/content/renderer/password_generation_agent.cc
+++ b/components/autofill/content/renderer/password_generation_agent.cc
@@ -126,6 +126,7 @@
       generation_popup_shown_(false),
       editing_popup_shown_(false),
       enabled_(password_generation::IsPasswordGenerationEnabled()),
+      form_classifier_enabled_(false),
       password_agent_(password_agent) {
   VLOG(2) << "Password Generation is " << (enabled_ ? "Enabled" : "Disabled");
 }
@@ -195,9 +196,15 @@
   FindPossibleGenerationForm();
 }
 
+void PasswordGenerationAgent::OnAllowToRunFormClassifier() {
+  form_classifier_enabled_ = true;
+}
+
 void PasswordGenerationAgent::RunFormClassifierAndSaveVote(
     const blink::WebFormElement& web_form,
     const PasswordForm& form) {
+  DCHECK(form_classifier_enabled_);
+
   base::string16 generation_field;
   ClassifyFormAndFindGenerationField(web_form, &generation_field);
   Send(new AutofillHostMsg_SaveGenerationFieldDetectedByClassifier(
@@ -242,7 +249,8 @@
     if (GetAccountCreationPasswordFields(
             form_util::ExtractAutofillableElementsInForm(forms[i]),
             &passwords)) {
-      RunFormClassifierAndSaveVote(forms[i], *password_form);
+      if (form_classifier_enabled_)
+        RunFormClassifierAndSaveVote(forms[i], *password_form);
       AccountCreationFormData ac_form_data(
           make_linked_ptr(password_form.release()), passwords);
       possible_account_creation_forms_.push_back(ac_form_data);
@@ -283,6 +291,8 @@
                         OnFormsEligibleForGenerationFound);
     IPC_MESSAGE_HANDLER(AutofillMsg_UserTriggeredGeneratePassword,
                         OnUserTriggeredGeneratePassword);
+    IPC_MESSAGE_HANDLER(AutofillMsg_AllowToRunFormClassifier,
+                        OnAllowToRunFormClassifier);
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
diff --git a/components/autofill/content/renderer/password_generation_agent.h b/components/autofill/content/renderer/password_generation_agent.h
index 9e1bda3..47f3a91 100644
--- a/components/autofill/content/renderer/password_generation_agent.h
+++ b/components/autofill/content/renderer/password_generation_agent.h
@@ -107,7 +107,12 @@
   // generation popup at this field.
   void OnUserTriggeredGeneratePassword();
 
+  // Enables the form classifier.
+  void OnAllowToRunFormClassifier();
+
   // Runs HTML parsing based classifier and saves its outcome to proto.
+  // TODO(crbug.com/621442): Remove client-side form classifier when server-side
+  // classifier is ready.
   void RunFormClassifierAndSaveVote(const blink::WebFormElement& web_form,
                                     const PasswordForm& form);
 
@@ -165,6 +170,9 @@
   // If this feature is enabled. Controlled by Finch.
   bool enabled_;
 
+  // If the form classifier should run.
+  bool form_classifier_enabled_;
+
   // Unowned pointer. Used to notify PassowrdAutofillAgent when values
   // in password fields are updated.
   PasswordAutofillAgent* password_agent_;
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h
index 52137e1a..d2db76e 100644
--- a/components/autofill/core/browser/autofill_field.h
+++ b/components/autofill/core/browser/autofill_field.h
@@ -175,6 +175,9 @@
   // The outcome of HTML parsing based form classifier.
   AutofillUploadContents::Field::FormClassifierOutcome form_classifier_outcome_;
 
+  // The value of the class attribute on the field, if present.
+  base::string16 css_classes_;
+
   DISALLOW_COPY_AND_ASSIGN(AutofillField);
 };
 
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc
index a5a89f60..a27d833 100644
--- a/components/autofill/core/browser/autofill_test_utils.cc
+++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -342,7 +342,8 @@
                      const char* control_type,
                      const char* label,
                      const char* autocomplete,
-                     unsigned autofill_type) {
+                     unsigned autofill_type,
+                     const char* css_classes) {
   field->set_signature(signature);
   if (name)
     field->set_name(name);
@@ -353,6 +354,8 @@
   if (autocomplete)
     field->set_autocomplete(autocomplete);
   field->set_autofill_type(autofill_type);
+  if (css_classes)
+    field->set_css_classes(css_classes);
 }
 
 void FillQueryField(AutofillQueryContents::Form::Field* field,
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h
index 5335374..677ab6c 100644
--- a/components/autofill/core/browser/autofill_test_utils.h
+++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -133,7 +133,8 @@
                      const char* control_type,
                      const char* label,
                      const char* autocomplete,
-                     unsigned autofill_type);
+                     unsigned autofill_type,
+                     const char* css_classes);
 
 // Fills the query form |field| with the information passed by parameter. If the
 // value of a const char* parameter is NULL, the corresponding attribute won't
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 485da9c..61bcd71 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -60,13 +60,6 @@
 // Maximum number of characters in the field label to be encoded in a proto.
 const int kMaxFieldLabelNumChars = 200;
 
-// Returns whether sending autofill field metadata to the server is enabled.
-bool IsAutofillFieldMetadataEnabled() {
-  const std::string group_name =
-      base::FieldTrialList::FindFullName("AutofillFieldMetadata");
-  return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
-}
-
 // Helper for |EncodeUploadRequest()| that creates a bit field corresponding to
 // |available_field_types| and returns the hex representation as a string.
 std::string EncodeFieldTypes(const ServerFieldTypeSet& available_field_types) {
@@ -572,6 +565,13 @@
   return forms;
 }
 
+// static
+bool FormStructure::IsAutofillFieldMetadataEnabled() {
+  const std::string group_name =
+      base::FieldTrialList::FindFullName("AutofillFieldMetadata");
+  return base::StartsWith(group_name, "Enabled", base::CompareCase::SENSITIVE);
+}
+
 std::string FormStructure::FormSignature() const {
   return base::Uint64ToString(FormSignature64Bit());
 }
@@ -1181,6 +1181,9 @@
 
         if (!field->autocomplete_attribute.empty())
           added_field->set_autocomplete(field->autocomplete_attribute);
+
+        if (!field->css_classes.empty())
+          added_field->set_css_classes(base::UTF16ToUTF8(field->css_classes));
       }
     }
   }
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index 01971c9..aab2a66 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -88,6 +88,9 @@
   static std::vector<FormDataPredictions> GetFieldTypePredictions(
       const std::vector<FormStructure*>& form_structures);
 
+  // Returns whether sending autofill field metadata to the server is enabled.
+  static bool IsAutofillFieldMetadataEnabled();
+
   // The unique signature for this form, composed of the target url domain,
   // the form name, and the form field names in a 64-bit hash.
   std::string FormSignature() const;
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 097628a..4038d56 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -2061,15 +2061,15 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 3763331450U, "firstname", "text",
-                        "First Name", nullptr, 3U);
+                        "First Name", nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 3494530716U, "lastname", "text",
-                        "Last Name", nullptr, 5U);
+                        "Last Name", nullptr, 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1029417091U, "email", "email",
-                        "Email", nullptr, 9U);
+                        "Email", nullptr, 9U, nullptr);
   test::FillUploadField(upload.add_field(), 466116101U, "phone", "number",
-                        "Phone", nullptr, 14U);
+                        "Phone", nullptr, 14U, nullptr);
   test::FillUploadField(upload.add_field(), 2799270304U, "country",
-                        "select-one", "Country", nullptr, 36U);
+                        "select-one", "Country", nullptr, 36U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2117,7 +2117,7 @@
   // Create an additonal 8 fields (total of 13).
   for (int i = 0; i < 8; ++i) {
     test::FillUploadField(upload.add_field(), 509334676U, "address", "text",
-                          "Address", nullptr, 30U);
+                          "Address", nullptr, 30U, nullptr);
   }
   // Put the appropriate autofill type on the different address fields.
   upload.mutable_field(6)->set_autofill_type(31U);
@@ -2231,16 +2231,16 @@
   upload.set_login_form_signature(42);
 
   test::FillUploadField(upload.add_field(), 4224610201U, "firstname", "",
-                        "First Name", "given-name", 3U);
+                        "First Name", "given-name", 3U, nullptr);
   test::FillUploadField(upload.add_field(), 2786066110U, "lastname", "",
-                        "Last Name", "family-name", 5U);
+                        "Last Name", "family-name", 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1029417091U, "email", "email",
-                        "Email", "email", 9U);
+                        "Email", "email", 9U, nullptr);
   test::FillUploadField(upload.add_field(), 239111655U, "username", "text",
-                        "username", "email", 86U);
+                        "username", "email", 86U, nullptr);
   auto* upload_password_field = upload.add_field();
   test::FillUploadField(upload_password_field, 2051817934U, "password",
-                        "password", "password", "email", 76U);
+                        "password", "password", "email", 76U, nullptr);
   upload_password_field->set_generation_type(
       autofill::AutofillUploadContents::Field::
           MANUALLY_TRIGGERED_GENERATION_ON_SIGN_UP_FORM);
@@ -2310,11 +2310,11 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 3763331450U, "firstname", "text",
-                        "First Name", "given-name", 3U);
+                        "First Name", "given-name", 3U, nullptr);
   test::FillUploadField(upload.add_field(), 3494530716U, "lastname", "text",
-                        "Last Name", "family-name", 5U);
+                        "Last Name", "family-name", 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1029417091U, "email", "email",
-                        "Email", "email", 9U);
+                        "Email", "email", 9U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2378,11 +2378,11 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 3763331450U, "firstname", "text",
-                        "First Name", nullptr, 3U);
+                        "First Name", nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 3494530716U, "lastname", "text",
-                        "Last Name", nullptr, 5U);
+                        "Last Name", nullptr, 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1029417091U, "email", "email",
-                        "Email", nullptr, 9U);
+                        "Email", nullptr, 9U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2443,11 +2443,71 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        nullptr, nullptr, 3U);
+                        nullptr, nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        "Last Name", nullptr, 5U);
+                        "Last Name", nullptr, 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        "Email", nullptr, 9U);
+                        "Email", nullptr, 9U, nullptr);
+
+  std::string expected_upload_string;
+  ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
+
+  AutofillUploadContents encoded_upload;
+  EXPECT_TRUE(form_structure->EncodeUploadRequest(
+      available_field_types, true, std::string(), true, &encoded_upload));
+
+  std::string encoded_upload_string;
+  encoded_upload.SerializeToString(&encoded_upload_string);
+  EXPECT_EQ(expected_upload_string, encoded_upload_string);
+}
+
+TEST_F(FormStructureTest, EncodeUploadRequest_WithCssClasses) {
+  std::vector<ServerFieldTypeSet> possible_field_types;
+  FormData form;
+
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  form.fields.push_back(field);
+  possible_field_types.push_back(ServerFieldTypeSet());
+  possible_field_types.back().insert(NAME_FIRST);
+
+  field.css_classes = ASCIIToUTF16("last_name_field");
+  form.fields.push_back(field);
+  possible_field_types.push_back(ServerFieldTypeSet());
+  possible_field_types.back().insert(NAME_LAST);
+
+  field.css_classes = ASCIIToUTF16("email_field required_field");
+  form.fields.push_back(field);
+  possible_field_types.push_back(ServerFieldTypeSet());
+  possible_field_types.back().insert(EMAIL_ADDRESS);
+
+  std::unique_ptr<FormStructure> form_structure(new FormStructure(form));
+
+  ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
+  for (size_t i = 0; i < form_structure->field_count(); ++i)
+    form_structure->field(i)->set_possible_types(possible_field_types[i]);
+
+  ServerFieldTypeSet available_field_types;
+  available_field_types.insert(NAME_FIRST);
+  available_field_types.insert(NAME_LAST);
+  available_field_types.insert(EMAIL_ADDRESS);
+
+  // Prepare the expected proto string.
+  AutofillUploadContents upload;
+  upload.set_submission(true);
+  upload.set_client_version("6.1.1715.1442/en (GGLL)");
+  upload.set_form_signature(6949133589768631292U);
+  upload.set_autofill_used(true);
+  upload.set_data_present("1440");
+  upload.set_action_signature(15724779818122431245U);
+
+  test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
+                        nullptr, nullptr, 3U, nullptr);
+  test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
+                        nullptr, nullptr, 5U, "last_name_field");
+  test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
+                        nullptr, nullptr, 9U, "email_field required_field");
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2508,11 +2568,11 @@
   upload.set_form_name("myform");
 
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        nullptr, nullptr, 3U);
+                        nullptr, nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        nullptr, nullptr, 5U);
+                        nullptr, nullptr, 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        nullptr, nullptr, 9U);
+                        nullptr, nullptr, 9U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2578,11 +2638,11 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 1318412689U, nullptr, "text",
-                        nullptr, nullptr, 3U);
+                        nullptr, nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 3494530716U, "lastname", "text",
-                        "Last Name", "family-name", 5U);
+                        "Last Name", "family-name", 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1545468175U, "lastname", "email",
-                        "Email", "email", 9U);
+                        "Email", "email", 9U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2612,6 +2672,7 @@
   field.label = ASCIIToUTF16("First Name");
   field.name = ASCIIToUTF16("firstname");
   field.autocomplete_attribute = "given-name";
+  field.css_classes = ASCIIToUTF16("class1 class2");
   form.fields.push_back(field);
   possible_field_types.push_back(ServerFieldTypeSet());
   possible_field_types.back().insert(NAME_FIRST);
@@ -2619,6 +2680,7 @@
   field.label = ASCIIToUTF16("Last Name");
   field.name = ASCIIToUTF16("lastname");
   field.autocomplete_attribute = "family-name";
+  field.css_classes = ASCIIToUTF16("class1 class2");
   form.fields.push_back(field);
   possible_field_types.push_back(ServerFieldTypeSet());
   possible_field_types.back().insert(NAME_LAST);
@@ -2627,6 +2689,7 @@
   field.name = ASCIIToUTF16("email");
   field.form_control_type = "email";
   field.autocomplete_attribute = "email";
+  field.css_classes = ASCIIToUTF16("class1 class2");
   form.fields.push_back(field);
   possible_field_types.push_back(ServerFieldTypeSet());
   possible_field_types.back().insert(EMAIL_ADDRESS);
@@ -2651,11 +2714,11 @@
   upload.set_data_present("1440");
 
   test::FillUploadField(upload.add_field(), 3763331450U, nullptr, nullptr,
-                        nullptr, nullptr, 3U);
+                        nullptr, nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 3494530716U, nullptr, nullptr,
-                        nullptr, nullptr, 5U);
+                        nullptr, nullptr, 5U, nullptr);
   test::FillUploadField(upload.add_field(), 1029417091U, nullptr, nullptr,
-                        nullptr, nullptr, 9U);
+                        nullptr, nullptr, 9U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2711,11 +2774,11 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 1089846351U, "first", "text",
-                        "First Name", nullptr, 1U);
+                        "First Name", nullptr, 1U, nullptr);
   test::FillUploadField(upload.add_field(), 2404144663U, "last", "text",
-                        "Last Name", nullptr, 1U);
+                        "Last Name", nullptr, 1U, nullptr);
   test::FillUploadField(upload.add_field(), 420638584U, "email", "text",
-                        "Email", nullptr, 1U);
+                        "Email", nullptr, 1U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -2979,13 +3042,13 @@
   upload.set_action_signature(15724779818122431245U);
 
   test::FillUploadField(upload.add_field(), 420638584U, "email", "text",
-                        "email", nullptr, 9U);
+                        "email", nullptr, 9U, nullptr);
   test::FillUploadField(upload.add_field(), 1089846351U, "first", "text",
-                        "First Name", nullptr, 3U);
+                        "First Name", nullptr, 3U, nullptr);
   test::FillUploadField(upload.add_field(), 2404144663U, "last", "text",
-                        "Last Name", nullptr, 5U);
+                        "Last Name", nullptr, 5U, nullptr);
   test::FillUploadField(upload.add_field(), 509334676U, "address", "text",
-                        "Address", nullptr, 30U);
+                        "Address", nullptr, 30U, nullptr);
 
   std::string expected_upload_string;
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
@@ -3007,10 +3070,10 @@
   upload.mutable_field(2)->set_autofill_type(3);
   // Replace the fourth field by the old third field.
   test::FillUploadField(upload.mutable_field(3), 2404144663U, "last", "text",
-                        "Last Name", nullptr, 5U);
+                        "Last Name", nullptr, 5U, nullptr);
   // Re-add the old fourth field.
   test::FillUploadField(upload.add_field(), 509334676U, "address", "text",
-                        "Address", nullptr, 30U);
+                        "Address", nullptr, 30U, nullptr);
 
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
 
@@ -3028,7 +3091,7 @@
 
   // Adjust the expected upload proto.
   test::FillUploadField(upload.add_field(), 509334676U, "address", "text",
-                        "Address", nullptr, 31U);
+                        "Address", nullptr, 31U, nullptr);
   ASSERT_TRUE(upload.SerializeToString(&expected_upload_string));
 
   AutofillUploadContents encoded_upload3;
diff --git a/components/autofill/core/browser/proto/server.proto b/components/autofill/core/browser/proto/server.proto
index 46bbfdb..5e6a9b7e 100644
--- a/components/autofill/core/browser/proto/server.proto
+++ b/components/autofill/core/browser/proto/server.proto
@@ -34,7 +34,7 @@
 
 // This message contains information about the field types in a single form.
 // It is sent by the toolbar to contribute to the field type statistics.
-// Next available id: 19
+// Next available id: 20
 message AutofillUploadContents {
   required string client_version = 1;
   required fixed64 form_signature = 2;
@@ -91,6 +91,9 @@
     }
     // The outcome of HTML parsing based form classifier.
     optional FormClassifierOutcome form_classifier_outcome = 18;
+
+    // The value of the class attribute on the field, if present.
+    optional string css_classes = 19;
   }
   // Signature of the form action host (e.g. Hash64Bit("example.com")).
   optional fixed64 action_signature = 13;
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc
index 992dd7ab..561ec4e 100644
--- a/components/autofill/core/common/form_field_data.cc
+++ b/components/autofill/core/common/form_field_data.cc
@@ -14,7 +14,7 @@
 
 // Increment this anytime pickle format is modified as well as provide
 // deserialization routine from previous kPickleVersion format.
-const int kPickleVersion = 4;
+const int kPickleVersion = 5;
 
 void AddVectorToPickle(std::vector<base::string16> strings,
                        base::Pickle* pickle) {
@@ -103,6 +103,11 @@
   return iter->ReadString16(&field_data->placeholder);
 }
 
+bool DeserializeSection8(base::PickleIterator* iter,
+                         FormFieldData* field_data) {
+  return iter->ReadString16(&field_data->css_classes);
+}
+
 }  // namespace
 
 FormFieldData::FormFieldData()
@@ -126,6 +131,7 @@
          form_control_type == field.form_control_type &&
          autocomplete_attribute == field.autocomplete_attribute &&
          placeholder == field.placeholder && max_length == field.max_length &&
+         css_classes == field.css_classes &&
          // is_checked and is_autofilled counts as "value" since these change
          // when we fill things in.
          IsCheckable(check_status) == IsCheckable(field.check_status) &&
@@ -160,6 +166,8 @@
   if (placeholder > field.placeholder) return false;
   if (max_length < field.max_length) return true;
   if (max_length > field.max_length) return false;
+  if (css_classes < field.css_classes) return true;
+  if (css_classes > field.css_classes) return false;
   // Skip |is_checked| and |is_autofilled| as in SameFieldAs.
   if (IsCheckable(check_status) < IsCheckable(field.check_status)) return true;
   if (IsCheckable(check_status) > IsCheckable(field.check_status)) return false;
@@ -193,6 +201,7 @@
   AddVectorToPickle(field_data.option_values, pickle);
   AddVectorToPickle(field_data.option_contents, pickle);
   pickle->WriteString16(field_data.placeholder);
+  pickle->WriteString16(field_data.css_classes);
 }
 
 bool DeserializeFormFieldData(base::PickleIterator* iter,
@@ -250,6 +259,19 @@
       }
       break;
     }
+    case 5: {
+      if (!DeserializeSection1(iter, &temp_form_field_data) ||
+          !DeserializeSection6(iter, &temp_form_field_data) ||
+          !DeserializeSection7(iter, &temp_form_field_data) ||
+          !DeserializeSection2(iter, &temp_form_field_data) ||
+          !DeserializeSection3(iter, &temp_form_field_data) ||
+          !DeserializeSection4(iter, &temp_form_field_data) ||
+          !DeserializeSection8(iter, &temp_form_field_data)) {
+        LOG(ERROR) << "Could not deserialize FormFieldData from pickle";
+        return false;
+      }
+      break;
+    }
     default: {
       LOG(ERROR) << "Unknown FormFieldData pickle version " << version;
       return false;
@@ -287,7 +309,7 @@
             << base::UTF16ToUTF8(field.name) << " "
             << base::UTF16ToUTF8(field.value) << " " << field.form_control_type
             << " " << field.autocomplete_attribute << " " << field.placeholder
-            << " " << field.max_length << " "
+            << " " << field.max_length << " " << field.css_classes << " "
             << (field.is_autofilled ? "true" : "false") << " "
             << check_status_str << (field.is_focusable ? "true" : "false")
             << " " << (field.should_autocomplete ? "true" : "false") << " "
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h
index b49e4519..689657c 100644
--- a/components/autofill/core/common/form_field_data.h
+++ b/components/autofill/core/common/form_field_data.h
@@ -53,6 +53,7 @@
   std::string form_control_type;
   std::string autocomplete_attribute;
   base::string16 placeholder;
+  base::string16 css_classes;
   // Note: we use uint64_t instead of size_t because this struct is sent over
   // IPC which could span 32 & 64 bit processes. We chose uint64_t instead of
   // uint32_t to maintain compatibility with old code which used size_t
@@ -98,6 +99,7 @@
     EXPECT_EQ(expected.autocomplete_attribute, actual.autocomplete_attribute); \
     EXPECT_EQ(expected.placeholder, actual.placeholder);                       \
     EXPECT_EQ(expected.max_length, actual.max_length);                         \
+    EXPECT_EQ(expected.css_classes, actual.css_classes);                       \
     EXPECT_EQ(expected.is_autofilled, actual.is_autofilled);                   \
     EXPECT_EQ(expected.check_status, actual.check_status);                     \
   } while (0)
diff --git a/components/autofill/core/common/form_field_data_unittest.cc b/components/autofill/core/common/form_field_data_unittest.cc
index 9dbd69f..a2e55c7 100644
--- a/components/autofill/core/common/form_field_data_unittest.cc
+++ b/components/autofill/core/common/form_field_data_unittest.cc
@@ -39,6 +39,10 @@
   data->placeholder = base::ASCIIToUTF16("placeholder");
 }
 
+void FillVersion5Fields(FormFieldData* data) {
+  data->css_classes = base::ASCIIToUTF16("class1 class2");
+}
+
 void WriteSection1(const FormFieldData& data, base::Pickle* pickle) {
   pickle->WriteString16(data.label);
   pickle->WriteString16(data.name);
@@ -81,6 +85,10 @@
   pickle->WriteString16(data.placeholder);
 }
 
+void WriteVersion5Specific(const FormFieldData& data, base::Pickle* pickle) {
+  pickle->WriteString16(data.css_classes);
+}
+
 void SerializeInVersion1Format(const FormFieldData& data,
                                base::Pickle* pickle) {
   WriteSection1(data, pickle);
@@ -118,6 +126,17 @@
   WriteVersion3Specific(data, pickle);
 }
 
+void SerializeInVersion5Format(const FormFieldData& data,
+                               base::Pickle* pickle) {
+  WriteSection1(data, pickle);
+  WriteSection4(data, pickle);
+  WriteSection5(data, pickle);
+  WriteVersion2Specific(data, pickle);
+  WriteSection2(data, pickle);
+  WriteVersion3Specific(data, pickle);
+  WriteVersion5Specific(data, pickle);
+}
+
 }  // namespace
 
 TEST(FormFieldDataTest, SerializeAndDeserialize) {
@@ -125,6 +144,7 @@
   FillCommonFields(&data);
   FillVersion2Fields(&data);
   FillVersion3Fields(&data);
+  FillVersion5Fields(&data);
 
   base::Pickle pickle;
   SerializeFormFieldData(data, &pickle);
@@ -201,6 +221,24 @@
   EXPECT_TRUE(actual.SameFieldAs(data));
 }
 
+TEST(FormFieldDataTest, DeserializeVersion5) {
+  FormFieldData data;
+  FillCommonFields(&data);
+  FillVersion2Fields(&data);
+  FillVersion3Fields(&data);
+  FillVersion5Fields(&data);
+
+  base::Pickle pickle;
+  pickle.WriteInt(5);
+  SerializeInVersion5Format(data, &pickle);
+
+  base::PickleIterator iter(pickle);
+  FormFieldData actual;
+  EXPECT_TRUE(DeserializeFormFieldData(&iter, &actual));
+
+  EXPECT_TRUE(actual.SameFieldAs(data));
+}
+
 // Verify that if the data isn't valid, the FormFieldData isn't populated
 // during deserialization.
 TEST(FormFieldDataTest, DeserializeBadData) {
diff --git a/components/bitmap_uploader/DEPS b/components/bitmap_uploader/DEPS
index 8b3486d6..bea586aa 100644
--- a/components/bitmap_uploader/DEPS
+++ b/components/bitmap_uploader/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+cc/ipc",
   "+components/mus/public",
   "+gpu/GLES2",
   "+mojo/common",
diff --git a/components/bitmap_uploader/bitmap_uploader.cc b/components/bitmap_uploader/bitmap_uploader.cc
index b79de43..f623ade4 100644
--- a/components/bitmap_uploader/bitmap_uploader.cc
+++ b/components/bitmap_uploader/bitmap_uploader.cc
@@ -9,6 +9,7 @@
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "cc/ipc/compositor_frame.mojom.h"
 #include "components/mus/public/cpp/gles2_context.h"
 #include "components/mus/public/cpp/surfaces/surfaces_type_converters.h"
 #include "components/mus/public/cpp/surfaces/surfaces_utils.h"
@@ -72,7 +73,7 @@
 void BitmapUploader::Upload() {
   const gfx::Rect bounds(window_->bounds());
   cc::mojom::RenderPassPtr pass = mojo::CreateDefaultPass(1, bounds);
-  mus::mojom::CompositorFramePtr frame = mus::mojom::CompositorFrame::New();
+  cc::mojom::CompositorFramePtr frame = cc::mojom::CompositorFrame::New();
 
   // TODO(rjkroege): Support device scale factor in PDF viewer
   frame->metadata.device_scale_factor = 1.0f;
diff --git a/components/bitmap_uploader/bitmap_uploader.h b/components/bitmap_uploader/bitmap_uploader.h
index 9ecde1dc..bd1b70d4 100644
--- a/components/bitmap_uploader/bitmap_uploader.h
+++ b/components/bitmap_uploader/bitmap_uploader.h
@@ -15,7 +15,7 @@
 #include "components/bitmap_uploader/bitmap_uploader_export.h"
 #include "components/mus/public/cpp/window_surface.h"
 #include "components/mus/public/cpp/window_surface_client.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
+#include "components/mus/public/interfaces/surface.mojom.h"
 #include "gpu/GLES2/gl2chromium.h"
 #include "gpu/GLES2/gl2extchromium.h"
 
diff --git a/components/browser_sync/browser/profile_sync_service.cc b/components/browser_sync/browser/profile_sync_service.cc
index 1b2911e..faa9e36 100644
--- a/components/browser_sync/browser/profile_sync_service.cc
+++ b/components/browser_sync/browser/profile_sync_service.cc
@@ -234,8 +234,8 @@
           base_directory_.Append(base::FilePath(kSyncDataFolderName))),
       catch_up_configure_in_progress_(false),
       passphrase_prompt_triggered_by_version_(false),
-      weak_factory_(this),
-      startup_controller_weak_factory_(this) {
+      sync_enabled_weak_factory_(this),
+      weak_factory_(this) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(sync_client_);
   std::string last_version = sync_prefs_.GetLastRunVersion();
@@ -265,11 +265,13 @@
 void ProfileSyncService::Initialize() {
   sync_client_->Initialize();
 
+  // We don't pass StartupController an Unretained reference to future-proof
+  // against the controller impl changing to post tasks.
   startup_controller_.reset(new browser_sync::StartupController(
       &sync_prefs_,
       base::Bind(&ProfileSyncService::CanBackendStart, base::Unretained(this)),
       base::Bind(&ProfileSyncService::StartUpSlowBackendComponents,
-                 startup_controller_weak_factory_.GetWeakPtr())));
+                 weak_factory_.GetWeakPtr())));
   std::unique_ptr<browser_sync::LocalSessionEventRouter> router(
       sync_client_->GetSyncSessionsClient()->GetLocalSessionEventRouter());
   local_device_ = sync_client_->GetSyncApiComponentFactory()
@@ -282,9 +284,9 @@
       sync_client_->GetSyncSessionsClient(), &sync_prefs_, local_device_.get(),
       std::move(router),
       base::Bind(&ProfileSyncService::NotifyForeignSessionUpdated,
-                 weak_factory_.GetWeakPtr()),
+                 sync_enabled_weak_factory_.GetWeakPtr()),
       base::Bind(&ProfileSyncService::TriggerRefresh,
-                 weak_factory_.GetWeakPtr(),
+                 sync_enabled_weak_factory_.GetWeakPtr(),
                  syncer::ModelTypeSet(syncer::SESSIONS))));
 
   if (channel_ == version_info::Channel::UNKNOWN &&
@@ -375,8 +377,9 @@
   AddObserver(sync_error_controller_.get());
 #endif
 
-  memory_pressure_listener_.reset(new base::MemoryPressureListener(base::Bind(
-      &ProfileSyncService::OnMemoryPressure, weak_factory_.GetWeakPtr())));
+  memory_pressure_listener_.reset(new base::MemoryPressureListener(
+      base::Bind(&ProfileSyncService::OnMemoryPressure,
+                 sync_enabled_weak_factory_.GetWeakPtr())));
   startup_controller_->Reset(GetRegisteredDataTypes());
   startup_controller_->TryStart();
 }
@@ -511,7 +514,7 @@
       credentials, delete_stale_data,
       std::unique_ptr<syncer::SyncManagerFactory>(
           new syncer::SyncManagerFactory()),
-      MakeWeakHandle(weak_factory_.GetWeakPtr()),
+      MakeWeakHandle(sync_enabled_weak_factory_.GetWeakPtr()),
       base::Bind(browser_sync::ChromeReportUnrecoverableError, channel_),
       http_post_provider_factory_getter, std::move(saved_nigori_state_));
 }
@@ -643,10 +646,9 @@
       next_token_request_time_ = base::Time::Now() +
           request_access_token_backoff_.GetTimeUntilRelease();
       request_access_token_retry_timer_.Start(
-            FROM_HERE,
-            request_access_token_backoff_.GetTimeUntilRelease(),
-            base::Bind(&ProfileSyncService::RequestAccessToken,
-                        weak_factory_.GetWeakPtr()));
+          FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(),
+          base::Bind(&ProfileSyncService::RequestAccessToken,
+                     sync_enabled_weak_factory_.GetWeakPtr()));
       NotifyObservers();
       break;
     }
@@ -768,7 +770,7 @@
   base::TimeDelta shutdown_time = base::Time::Now() - shutdown_start_time;
   UMA_HISTOGRAM_TIMES("Sync.Shutdown.BackendDestroyedTime", shutdown_time);
 
-  weak_factory_.InvalidateWeakPtrs();
+  sync_enabled_weak_factory_.InvalidateWeakPtrs();
 
   startup_controller_->Reset(GetRegisteredDataTypes());
 
@@ -894,10 +896,10 @@
 
   // Shut all data types down.
   base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::Bind(
-          &ProfileSyncService::ShutdownImpl, weak_factory_.GetWeakPtr(),
-          delete_sync_database ? syncer::DISABLE_SYNC : syncer::STOP_SYNC));
+      FROM_HERE, base::Bind(&ProfileSyncService::ShutdownImpl,
+                            sync_enabled_weak_factory_.GetWeakPtr(),
+                            delete_sync_database ? syncer::DISABLE_SYNC
+                                                 : syncer::STOP_SYNC));
 }
 
 void ProfileSyncService::ReenableDatatype(syncer::ModelType type) {
@@ -1106,10 +1108,9 @@
     } else  {
       request_access_token_backoff_.InformOfRequest(false);
       request_access_token_retry_timer_.Start(
-          FROM_HERE,
-          request_access_token_backoff_.GetTimeUntilRelease(),
+          FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(),
           base::Bind(&ProfileSyncService::RequestAccessToken,
-                     weak_factory_.GetWeakPtr()));
+                     sync_enabled_weak_factory_.GetWeakPtr()));
     }
   } else {
     // Reset backoff time after successful connection.
@@ -1300,8 +1301,9 @@
 
 void ProfileSyncService::ClearAndRestartSyncForPassphraseEncryption() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  backend_->ClearServerData(base::Bind(
-      &ProfileSyncService::OnClearServerDataDone, weak_factory_.GetWeakPtr()));
+  backend_->ClearServerData(
+      base::Bind(&ProfileSyncService::OnClearServerDataDone,
+                 sync_enabled_weak_factory_.GetWeakPtr()));
 }
 
 void ProfileSyncService::OnClearServerDataDone() {
diff --git a/components/browser_sync/browser/profile_sync_service.h b/components/browser_sync/browser/profile_sync_service.h
index 2108ecb..e498c03 100644
--- a/components/browser_sync/browser/profile_sync_service.h
+++ b/components/browser_sync/browser/profile_sync_service.h
@@ -1004,15 +1004,10 @@
   // this object was created on.
   base::ThreadChecker thread_checker_;
 
-  base::WeakPtrFactory<ProfileSyncService> weak_factory_;
+  // This weak factory invalidates its issued pointers when Sync is disabled.
+  base::WeakPtrFactory<ProfileSyncService> sync_enabled_weak_factory_;
 
-  // We don't use |weak_factory_| for the StartupController because the weak
-  // ptrs should be bound to the lifetime of ProfileSyncService and not to the
-  // [Initialize -> sync disabled/shutdown] lifetime.  We don't pass
-  // StartupController an Unretained reference to future-proof against
-  // the controller impl changing to post tasks. Therefore, we have a separate
-  // factory.
-  base::WeakPtrFactory<ProfileSyncService> startup_controller_weak_factory_;
+  base::WeakPtrFactory<ProfileSyncService> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileSyncService);
 };
diff --git a/components/cast_certificate/cast_cert_validator.cc b/components/cast_certificate/cast_cert_validator.cc
index 8a4d6eb4..6a81c84d 100644
--- a/components/cast_certificate/cast_cert_validator.cc
+++ b/components/cast_certificate/cast_cert_validator.cc
@@ -56,17 +56,18 @@
   friend struct base::DefaultSingletonTraits<CastTrustStore>;
 
   CastTrustStore() {
-    // Initialize the trust store with two root certificates.
+    AddAnchor(kCastRootCaDer);
+    AddAnchor(kEurekaRootCaDer);
+  }
+
+  // Adds a trust anchor given a DER-encoded certificate from static
+  // storage.
+  template <size_t N>
+  void AddAnchor(const uint8_t (&data)[N]) {
     scoped_refptr<net::ParsedCertificate> root =
         net::ParsedCertificate::CreateFromCertificateData(
-            kCastRootCaDer, sizeof(kCastRootCaDer),
-            net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE);
-    CHECK(root);
-    store_.AddTrustedCertificate(std::move(root));
-
-    root = net::ParsedCertificate::CreateFromCertificateData(
-        kEurekaRootCaDer, sizeof(kEurekaRootCaDer),
-        net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE);
+            data, N, net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE,
+            {});
     CHECK(root);
     store_.AddTrustedCertificate(std::move(root));
   }
@@ -258,6 +259,22 @@
   std::vector<scoped_refptr<net::ParsedCertificate>>* certs_;
 };
 
+// Returns the parsing options used for Cast certificates.
+net::ParseCertificateOptions GetCertParsingOptions() {
+  net::ParseCertificateOptions options;
+
+  // Some cast intermediate certificates contain serial numbers that are
+  // 21 octets long, and might also not use valid DER encoding for an
+  // INTEGER (non-minimal encoding).
+  //
+  // Allow these sorts of serial numbers.
+  //
+  // TODO(eroman): At some point in the future this workaround will no longer be
+  // necessary. Should revisit this for removal in 2017 if not earlier.
+  options.allow_invalid_serial_numbers = true;
+  return options;
+}
+
 }  // namespace
 
 bool VerifyDeviceCert(const std::vector<std::string>& certs,
@@ -277,7 +294,7 @@
     if (!net::ParsedCertificate::CreateAndAddToVector(
             reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size(),
             net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE,
-            &input_chain)) {
+            GetCertParsingOptions(), &input_chain)) {
       return false;
     }
   }
@@ -309,8 +326,8 @@
 bool AddTrustAnchorForTest(const uint8_t* data, size_t length) {
   scoped_refptr<net::ParsedCertificate> anchor(
       net::ParsedCertificate::CreateFromCertificateData(
-          data, length,
-          net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE));
+          data, length, net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE,
+          GetCertParsingOptions()));
   if (!anchor)
     return false;
   CastTrustStore::Get().AddTrustedCertificate(std::move(anchor));
diff --git a/components/cast_certificate/cast_cert_validator_unittest.cc b/components/cast_certificate/cast_cert_validator_unittest.cc
index 37999427..e363a1d 100644
--- a/components/cast_certificate/cast_cert_validator_unittest.cc
+++ b/components/cast_certificate/cast_cert_validator_unittest.cc
@@ -279,6 +279,27 @@
           "signeddata/AudioReferenceDevTest.pem");
 }
 
+// Tests verifying a valid certificate chain of length 3. Note that the first
+// intermediate has a serial number that is 21 octets long, which violates RFC
+// 5280. However cast verification accepts this certificate for compatibility
+// reasons.
+//
+//  0: 8C579B806FFC8A9DFFFF F8:8F:CA:6B:E6:DA
+//  1: Sony so16vic CA
+//  2: Cast Audio Sony CA
+//
+// Chains to trust anchor:
+//   Cast Root CA     (not included)
+//
+// This device certificate has a policy that means it is valid only for audio
+// devices.
+TEST(VerifyCastDeviceCertTest, IntermediateSerialNumberTooLong) {
+  RunTest(RESULT_SUCCESS, "8C579B806FFC8A9DFFFF F8:8F:CA:6B:E6:DA",
+          CastDeviceCertPolicy::AUDIO_ONLY,
+          "certificates/intermediate_serialnumber_toolong.pem",
+          AprilFirst2016(), "");
+}
+
 // ------------------------------------------------------
 // Valid signature using 1024-bit RSA key
 // ------------------------------------------------------
diff --git a/components/cdm/common/OWNERS b/components/cdm/common/OWNERS
index 6277118..42444bc 100644
--- a/components/cdm/common/OWNERS
+++ b/components/cdm/common/OWNERS
@@ -1,2 +1,2 @@
-per-file *messages*.h=set noparent
-per-file *messages*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/components/components.gyp b/components/components.gyp
index 5385d2e..df4ea5c 100644
--- a/components/components.gyp
+++ b/components/components.gyp
@@ -125,6 +125,7 @@
         'display_compositor.gypi',
         'domain_reliability.gypi',
         'drive.gypi',
+        'memory_coordinator.gypi',
         'navigation_interception.gypi',
         'network_hints.gypi',
         'packed_ct_ev_whitelist.gypi',
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index c33c06c2..9b4ee95 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -360,6 +360,9 @@
     'login_unittest_sources': [
       'login/screens/screen_context_unittest.cc',
     ],
+    'memory_coordinator_unittest_sources': [
+      'memory_coordinator/child/child_memory_coordinator_impl_unittest.cc',
+    ],
     'memory_pressure_unittest_sources': [
       'memory_pressure/direct_memory_pressure_calculator_linux_unittest.cc',
       'memory_pressure/direct_memory_pressure_calculator_win_unittest.cc',
@@ -785,6 +788,9 @@
       'storage_monitor/storage_monitor_unittest.cc',
       'storage_monitor/storage_monitor_win_unittest.cc',
     ],
+    'subresource_filter_content_browser_unittest_sources': [
+      'subresource_filter/content/browser/content_ruleset_distributor_unittest.cc',
+    ],
     'subresource_filter_core_browser_unittest_sources': [
       'subresource_filter/core/browser/ruleset_service_unittest.cc',
       'subresource_filter/core/browser/subresource_filter_features_unittest.cc',
@@ -1281,6 +1287,7 @@
             '<@(domain_reliability_unittest_sources)',
             '<@(error_page_unittest_sources)',
             '<@(guest_view_unittest_sources)',
+            '<@(memory_coordinator_unittest_sources)',
             '<@(navigation_interception_unittest_sources)',
             '<@(network_hints_unittest_sources)',
             '<@(ntp_tiles_unittest_sources)',
@@ -1291,6 +1298,7 @@
             '<@(safe_json_unittest_sources)',
             '<@(scheduler_unittest_sources)',
             '<@(storage_monitor_unittest_sources)',
+            '<@(subresource_filter_content_browser_unittest_sources)',
             '<@(tracing_unittest_sources)',
             '<@(visitedlink_unittest_sources)',
             '<@(wallpaper_unittest_sources)',
@@ -1322,6 +1330,7 @@
             'components.gyp:guest_view_test_support',
             'components.gyp:history_content_browser',
             'components.gyp:keyed_service_content',
+            'components.gyp:memory_coordinator_child',
             'components.gyp:metrics_gpu',
             'components.gyp:navigation_interception',
             'components.gyp:network_hints_renderer',
@@ -1338,6 +1347,8 @@
             'components.gyp:sessions_content',
             'components.gyp:storage_monitor',
             'components.gyp:storage_monitor_test_support',
+            'components.gyp:subresource_filter_content_browser',
+            'components.gyp:subresource_filter_content_common',
             'components.gyp:test_database_manager',
             'components.gyp:url_matcher',
             'components.gyp:visitedlink_browser',
diff --git a/components/data_reduction_proxy/OWNERS b/components/data_reduction_proxy/OWNERS
index e388021..85817a2f 100644
--- a/components/data_reduction_proxy/OWNERS
+++ b/components/data_reduction_proxy/OWNERS
@@ -5,5 +5,8 @@
 sclittle@chromium.org
 tbansal@chromium.org
 
-per-file *_messages.*=set noparent
-per-file *_messages.*=file://ipc/SECURITY_OWNERS
+per-file *_messages.cc=set noparent
+per-file *_messages.cc=file://ipc/SECURITY_OWNERS
+
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/components/exo/display.cc b/components/exo/display.cc
index e3a34806..7039936 100644
--- a/components/exo/display.cc
+++ b/components/exo/display.cc
@@ -110,9 +110,9 @@
     return nullptr;
   }
 
-  return base::WrapUnique(new ShellSurface(
-      surface, nullptr, gfx::Rect(), true /* activatable */, false /* shadow */,
-      ash::kShellWindowId_DefaultContainer));
+  return base::WrapUnique(
+      new ShellSurface(surface, nullptr, gfx::Rect(), true /* activatable */,
+                       ash::kShellWindowId_DefaultContainer));
 }
 
 std::unique_ptr<ShellSurface> Display::CreatePopupShellSurface(
@@ -143,7 +143,6 @@
 
   return base::WrapUnique(
       new ShellSurface(surface, parent, initial_bounds, false /* activatable */,
-                       false, /* shadow */
                        ash::kShellWindowId_DefaultContainer));
 }
 
@@ -159,8 +158,7 @@
   }
 
   return base::WrapUnique(new ShellSurface(surface, nullptr, gfx::Rect(1, 1),
-                                           true /* activatable */,
-                                           true /* shadow */, container));
+                                           true /* activatable */, container));
 }
 
 std::unique_ptr<SubSurface> Display::CreateSubSurface(Surface* surface,
diff --git a/components/exo/pointer_unittest.cc b/components/exo/pointer_unittest.cc
index e943033..5549834 100644
--- a/components/exo/pointer_unittest.cc
+++ b/components/exo/pointer_unittest.cc
@@ -173,7 +173,7 @@
   std::unique_ptr<Surface> child_surface(new Surface);
   std::unique_ptr<ShellSurface> child_shell_surface(new ShellSurface(
       child_surface.get(), shell_surface.get(), gfx::Rect(9, 9, 1, 1), true,
-      false, ash::kShellWindowId_DefaultContainer));
+      ash::kShellWindowId_DefaultContainer));
   gfx::Size child_buffer_size(15, 15);
   std::unique_ptr<Buffer> child_buffer(
       new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(child_buffer_size)));
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 08cb852..2641913 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -28,9 +28,6 @@
 #include "ui/base/hit_test.h"
 #include "ui/gfx/path.h"
 #include "ui/views/widget/widget.h"
-#include "ui/wm/core/shadow.h"
-#include "ui/wm/core/shadow_controller.h"
-#include "ui/wm/core/shadow_types.h"
 #include "ui/wm/core/window_util.h"
 #include "ui/wm/public/activation_client.h"
 
@@ -214,7 +211,6 @@
                            ShellSurface* parent,
                            const gfx::Rect& initial_bounds,
                            bool activatable,
-                           bool shadow_enabled,
                            int container)
     : widget_(nullptr),
       surface_(surface),
@@ -228,8 +224,7 @@
       scoped_configure_(nullptr),
       ignore_window_bounds_changes_(false),
       resize_component_(HTCAPTION),
-      pending_resize_component_(HTCAPTION),
-      shadow_enabled_(shadow_enabled) {
+      pending_resize_component_(HTCAPTION) {
   ash::Shell::GetInstance()->activation_client()->AddObserver(this);
   surface_->SetSurfaceDelegate(this);
   surface_->AddSurfaceObserver(this);
@@ -244,13 +239,11 @@
                    nullptr,
                    gfx::Rect(),
                    true,
-                   false,
                    ash::kShellWindowId_DefaultContainer) {}
 
 ShellSurface::~ShellSurface() {
   DCHECK(!scoped_configure_);
   ash::Shell::GetInstance()->activation_client()->RemoveObserver(this);
-  shadow_parent_.reset();
   if (surface_) {
     if (scale_ != 1.0)
       surface_->window()->SetTransform(gfx::Transform());
@@ -494,7 +487,6 @@
     geometry_ = pending_geometry_;
 
     UpdateWidgetBounds();
-    UpdateShadow();
 
     gfx::Point surface_origin = GetSurfaceOrigin();
     gfx::Rect hit_test_bounds =
@@ -690,12 +682,6 @@
     surface_->window()->SetBounds(
         gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size()));
 
-    // The shadow size may be updated to match the widget. Change it back
-    // to the opaque content size.
-    // TODO(oshima): When the arc window reiszing is enabled, we may want to
-    // implement shadow management here instead of using shadow controller.
-    UpdateShadow();
-
     Configure();
   }
 }
@@ -1095,34 +1081,4 @@
       gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size()));
 }
 
-void ShellSurface::UpdateShadow() {
-  if (!widget_ || !shadow_enabled_)
-    return;
-
-  aura::Window* window = widget_->GetNativeWindow();
-  wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window);
-  if (shadow) {
-    SkRegion opaque_region = surface_->ComputeOpaqueRegionForHierarchy();
-    if (opaque_region.isEmpty() || !opaque_region.isRect()) {
-      wm::SetShadowType(window, wm::SHADOW_TYPE_NONE);
-    } else {
-      ui::Layer* shadow_layer = shadow->layer();
-      if (!shadow_parent_) {
-        shadow_parent_ = base::WrapUnique(new aura::Window(nullptr));
-        shadow_parent_->set_ignore_events(true);
-        shadow_parent_->Init(ui::LAYER_NOT_DRAWN);
-        shadow_parent_->layer()->Add(shadow_layer);
-        window->AddChild(shadow_parent_.get());
-        shadow_parent_->Show();
-      }
-      gfx::Rect opaque_bounds(gfx::SkIRectToRect(opaque_region.getBounds()));
-      aura::Window::ConvertRectToTarget(window->parent(), window,
-                                        &opaque_bounds);
-      shadow_parent_->SetBounds(opaque_bounds);
-      shadow->SetContentBounds(gfx::Rect(opaque_bounds.size()));
-      wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR);
-    }
-  }
-}
-
 }  // namespace exo
diff --git a/components/exo/shell_surface.h b/components/exo/shell_surface.h
index 3342cf5..091e962e 100644
--- a/components/exo/shell_surface.h
+++ b/components/exo/shell_surface.h
@@ -49,7 +49,6 @@
                ShellSurface* parent,
                const gfx::Rect& initial_bounds,
                bool activatable,
-               bool shadow_enabled,
                int container);
   explicit ShellSurface(Surface* surface);
   ~ShellSurface() override;
@@ -241,10 +240,6 @@
   // Updates the bounds of widget to match the current surface bounds.
   void UpdateWidgetBounds();
 
-  // Creates, deletes and update the shadow bounds to match the
-  // current surface output bounds.
-  void UpdateShadow();
-
   views::Widget* widget_;
   Surface* surface_;
   aura::Window* parent_;
@@ -270,8 +265,6 @@
   gfx::Vector2d pending_origin_config_offset_;
   int resize_component_;  // HT constant (see ui/base/hit_test.h)
   int pending_resize_component_;
-  bool shadow_enabled_;
-  std::unique_ptr<aura::Window> shadow_parent_;
   std::deque<Config> pending_configs_;
   std::unique_ptr<ash::WindowResizer> resizer_;
   std::unique_ptr<ScopedAnimationsDisabled> scoped_animations_disabled_;
diff --git a/components/exo/shell_surface_unittest.cc b/components/exo/shell_surface_unittest.cc
index da8bfa2..1c252d2 100644
--- a/components/exo/shell_surface_unittest.cc
+++ b/components/exo/shell_surface_unittest.cc
@@ -2,15 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ash/common/shell_window_ids.h"
 #include "ash/common/wm/window_state.h"
 #include "ash/wm/window_state_aura.h"
 #include "base/message_loop/message_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/exo/buffer.h"
-#include "components/exo/display.h"
 #include "components/exo/shell_surface.h"
-#include "components/exo/sub_surface.h"
 #include "components/exo/surface.h"
 #include "components/exo/test/exo_test_base.h"
 #include "components/exo/test/exo_test_helper.h"
@@ -18,9 +15,6 @@
 #include "ui/aura/window.h"
 #include "ui/base/hit_test.h"
 #include "ui/views/widget/widget.h"
-#include "ui/wm/core/shadow.h"
-#include "ui/wm/core/shadow_controller.h"
-#include "ui/wm/core/shadow_types.h"
 #include "ui/wm/core/window_util.h"
 
 namespace exo {
@@ -358,107 +352,5 @@
   EXPECT_TRUE(is_resizing);
 }
 
-TEST_F(ShellSurfaceTest, Shadow) {
-  std::unique_ptr<Surface> surface(new Surface);
-  std::unique_ptr<ShellSurface> shell_surface(
-      new ShellSurface(surface.get(), nullptr, gfx::Rect(), true, true,
-                       ash::kShellWindowId_DefaultContainer));
-
-  surface->Commit();
-
-  views::Widget* widget = shell_surface->GetWidget();
-  aura::Window* window = widget->GetNativeWindow();
-
-  // 1) Initial state, no shadow.
-  wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window);
-  ASSERT_TRUE(shadow);
-  EXPECT_FALSE(shadow->layer()->visible());
-
-  std::unique_ptr<Display> display(new Display);
-
-  // 2) Create a new layout with default blending mode SrcOver.
-  // Theshadow shouldn't be visible.
-  std::unique_ptr<Surface> child = display->CreateSurface();
-  gfx::Size buffer_size(128, 128);
-  std::unique_ptr<Buffer> child_buffer(
-      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
-  child->Attach(child_buffer.get());
-  std::unique_ptr<SubSurface> sub_surface(
-      display->CreateSubSurface(child.get(), surface.get()));
-  surface->Commit();
-
-  EXPECT_FALSE(shadow->layer()->visible());
-
-  // 3) Making the surface the opaque should will make the shadow visible.
-  child->SetBlendMode(SkXfermode::kSrc_Mode);
-  child->Commit();
-  surface->Commit();
-  EXPECT_TRUE(shadow->layer()->visible());
-
-  gfx::Rect before = shadow->layer()->bounds();
-  gfx::Insets shadow_insets =
-      child.get()->window()->layer()->bounds().InsetsFrom(before);
-
-  // 4) Shadow size should be adjusted to the content size.
-  gfx::Size new_buffer_size(256, 256);
-  std::unique_ptr<Buffer> new_child_buffer(
-      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(new_buffer_size)));
-  child->Attach(new_child_buffer.get());
-  child->Commit();
-  surface->Commit();
-
-  gfx::Rect after(new_buffer_size);
-  after.Inset(shadow_insets);
-  EXPECT_NE(before, after);
-  EXPECT_EQ(after, shadow->layer()->bounds());
-
-  // 4) Updating the widget's window bounds should not change the shadow bounds.
-  window->SetBounds(gfx::Rect(0, 0, 100, 100));
-  EXPECT_EQ(after, shadow->layer()->bounds());
-
-  // 5) Create a opaque sub sub surface with offset so that the opaque region is
-  // non rectangular. Shadow will be disabled.
-  std::unique_ptr<Surface> sub_child = display->CreateSurface();
-  std::unique_ptr<Buffer> new_sub_child_buffer(
-      new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(new_buffer_size)));
-  sub_child->Attach(new_sub_child_buffer.get());
-  sub_child->SetBlendMode(SkXfermode::kSrc_Mode);
-  sub_child->Commit();
-  std::unique_ptr<SubSurface> sub_sub_surface(
-      display->CreateSubSurface(sub_child.get(), child.get()));
-  child->SetSubSurfacePosition(sub_child.get(), gfx::Point(10, 10));
-  child->Commit();
-  surface->Commit();
-
-  EXPECT_EQ(wm::SHADOW_TYPE_NONE, wm::GetShadowType(window));
-  EXPECT_FALSE(shadow->layer()->visible());
-
-  // 6) Making the sub sub surface non opaque makes opaque region rectangular
-  // again,
-  // and should enable the shadow again.
-  sub_child->SetBlendMode(SkXfermode::kSrcOver_Mode);
-  sub_child->Commit();
-  child->Commit();
-  surface->Commit();
-
-  EXPECT_EQ(wm::SHADOW_TYPE_RECTANGULAR, wm::GetShadowType(window));
-  EXPECT_TRUE(shadow->layer()->visible());
-
-  // 7) Delete the sub surface and it should disable the shadow.
-  sub_surface.reset();
-  surface->Commit();
-
-  EXPECT_EQ(wm::SHADOW_TYPE_NONE, wm::GetShadowType(window));
-  EXPECT_FALSE(shadow->layer()->visible());
-
-  // 8) Create subsurface again, and it should enable the shadow.
-  sub_surface = display->CreateSubSurface(child.get(), surface.get());
-  surface->Commit();
-
-  EXPECT_TRUE(shadow->layer()->visible());
-  EXPECT_EQ(wm::SHADOW_TYPE_RECTANGULAR, wm::GetShadowType(window));
-  EXPECT_TRUE(shadow->layer()->visible());
-}
-
 }  // namespace
 }  // namespace exo
diff --git a/components/exo/surface.cc b/components/exo/surface.cc
index f7f5ccf4..2c2edd9 100644
--- a/components/exo/surface.cc
+++ b/components/exo/surface.cc
@@ -713,25 +713,6 @@
     SetSurfaceHierarchyNeedsCommitToNewSurfaces();
 }
 
-SkRegion Surface::ComputeOpaqueRegionForHierarchy() const {
-  SkRegion opaque_region;
-
-  if (state_.blend_mode == SkXfermode::kSrc_Mode)
-    opaque_region.setRect(gfx::RectToSkIRect(gfx::Rect(content_size_)));
-
-  for (const auto& sub_surface_entry : pending_sub_surfaces_) {
-    SkRegion opaque_sub_surface_region =
-        sub_surface_entry.first->ComputeOpaqueRegionForHierarchy();
-    if (!opaque_sub_surface_region.isEmpty()) {
-      gfx::Point origin = sub_surface_entry.first->window()->bounds().origin();
-      opaque_sub_surface_region.translate(origin.x(), origin.y());
-      opaque_region.op(opaque_sub_surface_region, SkRegion::kUnion_Op);
-    }
-  }
-
-  return opaque_region;
-}
-
 Surface::State::State() : input_region(SkIRect::MakeLargest()) {}
 
 Surface::State::~State() = default;
diff --git a/components/exo/surface.h b/components/exo/surface.h
index 3b587e0..45395e95 100644
--- a/components/exo/surface.h
+++ b/components/exo/surface.h
@@ -230,10 +230,6 @@
   template <typename T>
   void ClearProperty(const SurfaceProperty<T>* property);
 
-  // Returns the union of all opaque regions in surface hierarchy relative
-  // to the surface's origin.
-  SkRegion ComputeOpaqueRegionForHierarchy() const;
-
  private:
   struct State {
     State();
diff --git a/components/memory_coordinator.gypi b/components/memory_coordinator.gypi
new file mode 100644
index 0000000..bb848e14
--- /dev/null
+++ b/components/memory_coordinator.gypi
@@ -0,0 +1,42 @@
+# Copyright (c) 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'targets': [
+    {
+      # GN version: //components/memory_coordinator/public/interfaces
+      'target_name': 'memory_coordinator_mojo_bindings',
+      'type': 'static_library',
+      'sources': [
+        'memory_coordinator/public/interfaces/child_memory_coordinator.mojom',
+      ],
+      'includes': [ '../mojo/mojom_bindings_generator.gypi' ],
+    },
+    {
+      # GN version: //components/memory_coordinator/common
+      'target_name': 'memory_coordinator_common',
+      'type': 'none',
+      'dependencies': [
+        'memory_coordinator_mojo_bindings',
+      ],
+      'sources': [
+        'memory_coordinator/common/memory_coordinator_client.h',
+      ],
+    },
+    {
+      # GN version: //components/memory_coordinator/child
+      'target_name': 'memory_coordinator_child',
+      'type': 'static_library',
+      'dependencies': [
+        '<(DEPTH)/base/base.gyp:base',
+        'memory_coordinator_common',
+        'memory_coordinator_mojo_bindings',
+      ],
+      'sources': [
+        'memory_coordinator/child/child_memory_coordinator_impl.cc',
+        'memory_coordinator/child/child_memory_coordinator_impl.h',
+      ],
+    },
+  ],
+}
diff --git a/components/memory_coordinator/DEPS b/components/memory_coordinator/DEPS
new file mode 100644
index 0000000..ef8ad28
--- /dev/null
+++ b/components/memory_coordinator/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+mojo/public",
+]
diff --git a/components/memory_coordinator/OWNERS b/components/memory_coordinator/OWNERS
new file mode 100644
index 0000000..26ad3ee
--- /dev/null
+++ b/components/memory_coordinator/OWNERS
@@ -0,0 +1,3 @@
+bashi@chromium.org
+chrisha@chromium.org
+haraken@chromium.org
diff --git a/components/memory_coordinator/child/BUILD.gn b/components/memory_coordinator/child/BUILD.gn
new file mode 100644
index 0000000..db58c2d
--- /dev/null
+++ b/components/memory_coordinator/child/BUILD.gn
@@ -0,0 +1,30 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("child") {
+  sources = [
+    "child_memory_coordinator_impl.cc",
+    "child_memory_coordinator_impl.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/memory_coordinator/common",
+    "//components/memory_coordinator/public/interfaces",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+
+  sources = [
+    "child_memory_coordinator_impl_unittest.cc",
+  ]
+
+  deps = [
+    ":child",
+    "//mojo/common",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/memory_coordinator/child/child_memory_coordinator_impl.cc b/components/memory_coordinator/child/child_memory_coordinator_impl.cc
new file mode 100644
index 0000000..75889ed
--- /dev/null
+++ b/components/memory_coordinator/child/child_memory_coordinator_impl.cc
@@ -0,0 +1,22 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/memory_coordinator/child/child_memory_coordinator_impl.h"
+
+namespace memory_coordinator {
+
+ChildMemoryCoordinatorImpl::ChildMemoryCoordinatorImpl(
+      mojo::InterfaceRequest<mojom::ChildMemoryCoordinator> request,
+      scoped_refptr<ClientList> clients)
+    : binding_(this, std::move(request)),
+      clients_(clients) {}
+
+ChildMemoryCoordinatorImpl::~ChildMemoryCoordinatorImpl() {}
+
+void ChildMemoryCoordinatorImpl::OnStateChange(mojom::MemoryState state) {
+  clients_->Notify(FROM_HERE, &MemoryCoordinatorClient::OnMemoryStateChange,
+                   state);
+}
+
+}  // namespace memory_coordinator
diff --git a/components/memory_coordinator/child/child_memory_coordinator_impl.h b/components/memory_coordinator/child/child_memory_coordinator_impl.h
new file mode 100644
index 0000000..bdb6376a
--- /dev/null
+++ b/components/memory_coordinator/child/child_memory_coordinator_impl.h
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_MEMORY_COORDINATOR_CHILD_CHILD_MEMORY_COORDINATOR_IMPL_H_
+#define COMPONENTS_MEMORY_COORDINATOR_CHILD_CHILD_MEMORY_COORDINATOR_IMPL_H_
+
+#include "base/compiler_specific.h"
+#include "base/observer_list_threadsafe.h"
+#include "components/memory_coordinator/common/memory_coordinator_client.h"
+#include "components/memory_coordinator/public/interfaces/child_memory_coordinator.mojom.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace memory_coordinator {
+
+// ChildMemoryCoordinatorImpl is the implementation of ChildMemoryCoordinator.
+// It lives in child processes and is responsible for dispatching memory events
+// to its clients.
+class ChildMemoryCoordinatorImpl
+    : NON_EXPORTED_BASE(public mojom::ChildMemoryCoordinator) {
+ public:
+  using ClientList = base::ObserverListThreadSafe<MemoryCoordinatorClient>;
+  ChildMemoryCoordinatorImpl(
+      mojo::InterfaceRequest<mojom::ChildMemoryCoordinator> request,
+      scoped_refptr<ClientList> clients);
+  ~ChildMemoryCoordinatorImpl() override;
+
+  // mojom::ChildMemoryCoordinator implementations:
+  void OnStateChange(mojom::MemoryState state) override;
+
+ private:
+  mojo::StrongBinding<mojom::ChildMemoryCoordinator> binding_;
+  scoped_refptr<ClientList> clients_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChildMemoryCoordinatorImpl);
+};
+
+}  // namespace content
+
+#endif  // COMPONENTS_MEMORY_COORDINATOR_CHILD_CHILD_MEMORY_COORDINATOR_IMPL_H_
diff --git a/components/memory_coordinator/child/child_memory_coordinator_impl_unittest.cc b/components/memory_coordinator/child/child_memory_coordinator_impl_unittest.cc
new file mode 100644
index 0000000..3b7db40
--- /dev/null
+++ b/components/memory_coordinator/child/child_memory_coordinator_impl_unittest.cc
@@ -0,0 +1,137 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/memory_coordinator/child/child_memory_coordinator_impl.h"
+
+#include <memory>
+
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace memory_coordinator {
+
+namespace {
+
+class ChildMemoryCoordinatorImplTest : public testing::Test {
+ public:
+  ChildMemoryCoordinatorImplTest()
+      : clients_(new ChildMemoryCoordinatorImpl::ClientList),
+        message_loop_(new base::MessageLoop),
+        coordinator_impl_(mojo::GetProxy(&coordinator_), clients_) {}
+
+  void RegisterClient(MemoryCoordinatorClient* client) {
+    clients_->AddObserver(client);
+  }
+
+  void UnregisterClient(MemoryCoordinatorClient* client) {
+    clients_->RemoveObserver(client);
+  }
+
+  mojom::ChildMemoryCoordinatorPtr& coordinator() { return coordinator_; }
+  ChildMemoryCoordinatorImpl& coordinator_impl() { return coordinator_impl_; }
+
+  void ChangeState(mojom::MemoryState state) {
+    base::RunLoop loop;
+    coordinator()->OnStateChange(state);
+    loop.RunUntilIdle();
+  }
+
+ protected:
+  scoped_refptr<ChildMemoryCoordinatorImpl::ClientList> clients_;
+
+ private:
+  std::unique_ptr<base::MessageLoop> message_loop_;
+  mojom::ChildMemoryCoordinatorPtr coordinator_ = nullptr;
+  ChildMemoryCoordinatorImpl coordinator_impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(ChildMemoryCoordinatorImplTest);
+};
+
+class MockMemoryCoordinatorClient final : public MemoryCoordinatorClient {
+public:
+  void OnMemoryStateChange(mojom::MemoryState state) override {
+    last_state_ = state;
+  }
+
+  mojom::MemoryState last_state() const { return last_state_; }
+
+ private:
+  mojom::MemoryState last_state_ = mojom::MemoryState::UNKNOWN;
+};
+
+class MemoryCoordinatorTestThread : public base::Thread,
+                                    public MemoryCoordinatorClient {
+ public:
+  MemoryCoordinatorTestThread(
+      const std::string& name,
+      scoped_refptr<ChildMemoryCoordinatorImpl::ClientList> clients)
+      : Thread(name), clients_(clients) {}
+  ~MemoryCoordinatorTestThread() override { Stop(); }
+
+  void Init() override {
+    clients_->AddObserver(this);
+  }
+
+  void OnMemoryStateChange(mojom::MemoryState state) override {
+    EXPECT_EQ(message_loop(), base::MessageLoop::current());
+    last_state_ = state;
+  }
+
+  void CheckLastState(mojom::MemoryState state) {
+    task_runner()->PostTask(
+        FROM_HERE,
+        base::Bind(&MemoryCoordinatorTestThread::CheckLastStateInternal,
+                   base::Unretained(this), state));
+  }
+
+ private:
+  void CheckLastStateInternal(mojom::MemoryState state) {
+    base::RunLoop loop;
+    loop.RunUntilIdle();
+    EXPECT_EQ(state, last_state_);
+  }
+
+  scoped_refptr<ChildMemoryCoordinatorImpl::ClientList> clients_;
+  mojom::MemoryState last_state_ = mojom::MemoryState::UNKNOWN;
+};
+
+TEST_F(ChildMemoryCoordinatorImplTest, SingleClient) {
+  MockMemoryCoordinatorClient client;
+  RegisterClient(&client);
+
+  ChangeState(mojom::MemoryState::THROTTLED);
+  EXPECT_EQ(mojom::MemoryState::THROTTLED, client.last_state());
+
+  ChangeState(mojom::MemoryState::NORMAL);
+  EXPECT_EQ(mojom::MemoryState::NORMAL, client.last_state());
+
+  UnregisterClient(&client);
+  ChangeState(mojom::MemoryState::THROTTLED);
+  EXPECT_TRUE(mojom::MemoryState::THROTTLED != client.last_state());
+}
+
+TEST_F(ChildMemoryCoordinatorImplTest, MultipleClients) {
+  MemoryCoordinatorTestThread t1("thread 1", clients_);
+  MemoryCoordinatorTestThread t2("thread 2", clients_);
+
+  t1.StartAndWaitForTesting();
+  t2.StartAndWaitForTesting();
+
+  ChangeState(mojom::MemoryState::THROTTLED);
+  t1.CheckLastState(mojom::MemoryState::THROTTLED);
+  t2.CheckLastState(mojom::MemoryState::THROTTLED);
+
+  ChangeState(mojom::MemoryState::NORMAL);
+  t1.CheckLastState(mojom::MemoryState::NORMAL);
+  t2.CheckLastState(mojom::MemoryState::NORMAL);
+
+  t1.Stop();
+  t2.Stop();
+}
+
+}  // namespace
+
+}  // namespace memory_coordinator
diff --git a/components/memory_coordinator/common/BUILD.gn b/components/memory_coordinator/common/BUILD.gn
new file mode 100644
index 0000000..950b137
--- /dev/null
+++ b/components/memory_coordinator/common/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("common") {
+  sources = [
+    "memory_coordinator_client.h",
+  ]
+
+  public_deps = [
+    "//components/memory_coordinator/public/interfaces",
+  ]
+}
diff --git a/components/memory_coordinator/common/memory_coordinator_client.h b/components/memory_coordinator/common/memory_coordinator_client.h
new file mode 100644
index 0000000..44a04ad
--- /dev/null
+++ b/components/memory_coordinator/common/memory_coordinator_client.h
@@ -0,0 +1,24 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEMORY_COORDINATOR_COMMON_MEMORY_COORDINATOR_CLIENT_H_
+#define MEMORY_COORDINATOR_COMMON_MEMORY_COORDINATOR_CLIENT_H_
+
+#include "components/memory_coordinator/public/interfaces/child_memory_coordinator.mojom.h"
+
+namespace memory_coordinator {
+
+// This is an interface for components which can respond to memory status
+// changes.
+class MemoryCoordinatorClient {
+ public:
+  virtual ~MemoryCoordinatorClient() {}
+
+  // Called when memory state has changed.
+  virtual void OnMemoryStateChange(mojom::MemoryState state) = 0;
+};
+
+}  // namespace memory_coordinator
+
+#endif  // MEMORY_COORDINATOR_COMMON_MEMORY_COORDINATOR_CLIENT_H_
diff --git a/components/memory_coordinator/public/interfaces/BUILD.gn b/components/memory_coordinator/public/interfaces/BUILD.gn
new file mode 100644
index 0000000..770bc29
--- /dev/null
+++ b/components/memory_coordinator/public/interfaces/BUILD.gn
@@ -0,0 +1,11 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+  sources = [
+    "child_memory_coordinator.mojom",
+  ]
+}
diff --git a/components/memory_coordinator/public/interfaces/OWNERS b/components/memory_coordinator/public/interfaces/OWNERS
new file mode 100644
index 0000000..b6fb12b
--- /dev/null
+++ b/components/memory_coordinator/public/interfaces/OWNERS
@@ -0,0 +1,4 @@
+# Changes to Mojo interfaces require a security review to avoid
+# introducing new sandbox escapes.
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
\ No newline at end of file
diff --git a/components/memory_coordinator/public/interfaces/child_memory_coordinator.mojom b/components/memory_coordinator/public/interfaces/child_memory_coordinator.mojom
new file mode 100644
index 0000000..59c653eb
--- /dev/null
+++ b/components/memory_coordinator/public/interfaces/child_memory_coordinator.mojom
@@ -0,0 +1,22 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module memory_coordinator.mojom;
+
+enum MemoryState {
+  UNKNOWN = -1,
+  NORMAL = 0,
+  THROTTLED = 1,
+  // TODO(bashi): Define SUSPENDED when we need it.
+  // SUSPENDED = 2,
+};
+
+// ChildMemoryCoordinator lives in a child process and receives memory events
+// dispatched by the central memory coordinator which lives in the browser
+// process.
+interface ChildMemoryCoordinator {
+  // Called when the central memory coodinator changes the state for child
+  // processes.
+  OnStateChange(MemoryState state);
+};
diff --git a/components/mus/common/mojo_gpu_memory_buffer.cc b/components/mus/common/mojo_gpu_memory_buffer.cc
index 6927574..00b046b 100644
--- a/components/mus/common/mojo_gpu_memory_buffer.cc
+++ b/components/mus/common/mojo_gpu_memory_buffer.cc
@@ -11,6 +11,8 @@
 #include "base/memory/shared_memory.h"
 #include "base/numerics/safe_conversions.h"
 #include "build/build_config.h"
+#include "mojo/public/cpp/system/buffer.h"
+#include "mojo/public/cpp/system/platform_handle.h"
 #include "ui/gfx/buffer_format_util.h"
 
 namespace mus {
@@ -30,11 +32,23 @@
     gfx::BufferFormat format,
     gfx::BufferUsage usage) {
   size_t bytes = gfx::BufferSizeForBufferFormat(size, format);
-  std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
 
-  if (!shared_memory->CreateAnonymous(bytes))
+  mojo::ScopedSharedBufferHandle handle =
+      mojo::SharedBufferHandle::Create(bytes);
+  if (!handle.is_valid())
     return nullptr;
 
+  base::SharedMemoryHandle platform_handle;
+  size_t shared_memory_size;
+  bool readonly;
+  MojoResult result = mojo::UnwrapSharedMemoryHandle(
+      std::move(handle), &platform_handle, &shared_memory_size, &readonly);
+  if (result != MOJO_RESULT_OK)
+    return nullptr;
+  DCHECK_EQ(shared_memory_size, bytes);
+
+  auto shared_memory =
+      base::MakeUnique<base::SharedMemory>(platform_handle, readonly);
   return base::WrapUnique<gfx::GpuMemoryBuffer>(
       new MojoGpuMemoryBufferImpl(size, format, std::move(shared_memory)));
 }
diff --git a/components/mus/gpu/display_compositor/compositor_frame_sink_impl.cc b/components/mus/gpu/display_compositor/compositor_frame_sink_impl.cc
index f4aad23..4c20a70 100644
--- a/components/mus/gpu/display_compositor/compositor_frame_sink_impl.cc
+++ b/components/mus/gpu/display_compositor/compositor_frame_sink_impl.cc
@@ -4,10 +4,10 @@
 
 #include "components/mus/gpu/display_compositor/compositor_frame_sink_impl.h"
 
+#include "cc/ipc/compositor_frame.mojom.h"
 #include "cc/surfaces/surface_factory.h"
 #include "components/mus/gpu/display_compositor/compositor_frame_sink_delegate.h"
 #include "components/mus/public/cpp/surfaces/surfaces_type_converters.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
 
 namespace mus {
 namespace gpu {
@@ -56,7 +56,7 @@
 }
 
 void CompositorFrameSinkImpl::SubmitCompositorFrame(
-    mus::mojom::CompositorFramePtr frame,
+    cc::mojom::CompositorFramePtr frame,
     const SubmitCompositorFrameCallback& callback) {
   // TODO(fsamuel): Validate that SurfaceDrawQuad refer to allowable surface
   // IDs.
diff --git a/components/mus/gpu/display_compositor/compositor_frame_sink_impl.h b/components/mus/gpu/display_compositor/compositor_frame_sink_impl.h
index e72ab6f..a0ae215 100644
--- a/components/mus/gpu/display_compositor/compositor_frame_sink_impl.h
+++ b/components/mus/gpu/display_compositor/compositor_frame_sink_impl.h
@@ -36,7 +36,7 @@
   // mojom::CompositorFrameSink implementation.
   void SetNeedsBeginFrame(bool needs_begin_frame) override;
   void SubmitCompositorFrame(
-      mus::mojom::CompositorFramePtr frame,
+      cc::mojom::CompositorFramePtr frame,
       const SubmitCompositorFrameCallback& callback) override;
 
  private:
diff --git a/components/mus/public/cpp/lib/output_surface.cc b/components/mus/public/cpp/lib/output_surface.cc
index 7c90261..f8237d5b 100644
--- a/components/mus/public/cpp/lib/output_surface.cc
+++ b/components/mus/public/cpp/lib/output_surface.cc
@@ -41,7 +41,7 @@
   // destroyed then SubmitCompositorFrame's callback will never get called.
   // Thus, base::Unretained is safe here.
   surface_->SubmitCompositorFrame(
-      mojom::CompositorFrame::From(*frame),
+      cc::mojom::CompositorFrame::From(*frame),
       base::Bind(&OutputSurface::SwapBuffersComplete, base::Unretained(this)));
 }
 
diff --git a/components/mus/public/cpp/lib/window_surface.cc b/components/mus/public/cpp/lib/window_surface.cc
index b8496114..32f17772 100644
--- a/components/mus/public/cpp/lib/window_surface.cc
+++ b/components/mus/public/cpp/lib/window_surface.cc
@@ -34,7 +34,7 @@
       this, std::move(client_request_)));
 }
 
-void WindowSurface::SubmitCompositorFrame(mojom::CompositorFramePtr frame,
+void WindowSurface::SubmitCompositorFrame(cc::mojom::CompositorFramePtr frame,
                                           const base::Closure& callback) {
   DCHECK(thread_checker_);
   DCHECK(thread_checker_->CalledOnValidThread());
diff --git a/components/mus/public/cpp/surfaces/OWNERS b/components/mus/public/cpp/surfaces/OWNERS
index c92691f..b0569a1 100644
--- a/components/mus/public/cpp/surfaces/OWNERS
+++ b/components/mus/public/cpp/surfaces/OWNERS
@@ -1 +1,4 @@
 fsamuel@chromium.org
+
+per-file *_type_converter*.*=set noparent
+per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
diff --git a/components/mus/public/cpp/surfaces/surfaces_type_converters.cc b/components/mus/public/cpp/surfaces/surfaces_type_converters.cc
index e869ba6..7c6e6a54 100644
--- a/components/mus/public/cpp/surfaces/surfaces_type_converters.cc
+++ b/components/mus/public/cpp/surfaces/surfaces_type_converters.cc
@@ -25,6 +25,8 @@
 #include "cc/quads/yuv_video_draw_quad.h"
 #include "cc/surfaces/surface_id_allocator.h"
 
+using cc::mojom::CompositorFrame;
+using cc::mojom::CompositorFramePtr;
 using cc::mojom::DebugBorderQuadState;
 using cc::mojom::DebugBorderQuadStatePtr;
 using cc::mojom::DrawQuad;
@@ -44,8 +46,6 @@
 using cc::mojom::YUVColorSpace;
 using cc::mojom::YUVVideoQuadState;
 using cc::mojom::YUVVideoQuadStatePtr;
-using mus::mojom::CompositorFrame;
-using mus::mojom::CompositorFramePtr;
 
 namespace mojo {
 
diff --git a/components/mus/public/cpp/surfaces/surfaces_type_converters.h b/components/mus/public/cpp/surfaces/surfaces_type_converters.h
index e84ff5e..7c44473 100644
--- a/components/mus/public/cpp/surfaces/surfaces_type_converters.h
+++ b/components/mus/public/cpp/surfaces/surfaces_type_converters.h
@@ -7,13 +7,13 @@
 
 #include <memory>
 
+#include "cc/ipc/compositor_frame.mojom.h"
 #include "cc/ipc/quads.mojom.h"
 #include "cc/ipc/surface_id.mojom.h"
 #include "cc/resources/returned_resource.h"
 #include "cc/resources/transferable_resource.h"
 #include "cc/surfaces/surface_id.h"
 #include "components/mus/public/cpp/surfaces/mojo_surfaces_export.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
 #include "gpu/command_buffer/common/sync_token.h"
@@ -54,20 +54,20 @@
 
 // Types from compositor_frame.mojom
 MOJO_SURFACES_EXPORT std::unique_ptr<cc::CompositorFrame>
-ConvertToCompositorFrame(const mus::mojom::CompositorFramePtr& input);
+ConvertToCompositorFrame(const cc::mojom::CompositorFramePtr& input);
 
 template <>
 struct MOJO_SURFACES_EXPORT
-    TypeConverter<mus::mojom::CompositorFramePtr, cc::CompositorFrame> {
-  static mus::mojom::CompositorFramePtr Convert(
+    TypeConverter<cc::mojom::CompositorFramePtr, cc::CompositorFrame> {
+  static cc::mojom::CompositorFramePtr Convert(
       const cc::CompositorFrame& input);
 };
 
 template <>
 struct MOJO_SURFACES_EXPORT TypeConverter<std::unique_ptr<cc::CompositorFrame>,
-                                          mus::mojom::CompositorFramePtr> {
+                                          cc::mojom::CompositorFramePtr> {
   static std::unique_ptr<cc::CompositorFrame> Convert(
-      const mus::mojom::CompositorFramePtr& input);
+      const cc::mojom::CompositorFramePtr& input);
 };
 
 }  // namespace mojo
diff --git a/components/mus/public/cpp/surfaces/surfaces_utils.h b/components/mus/public/cpp/surfaces/surfaces_utils.h
index 63164839..14e854c 100644
--- a/components/mus/public/cpp/surfaces/surfaces_utils.h
+++ b/components/mus/public/cpp/surfaces/surfaces_utils.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_MUS_PUBLIC_CPP_SURFACES_SURFACES_UTILS_H_
 #define COMPONENTS_MUS_PUBLIC_CPP_SURFACES_SURFACES_UTILS_H_
 
-#include "cc/ipc/quads.mojom.h"
+#include "cc/ipc/render_pass.mojom.h"
 #include "components/mus/public/cpp/surfaces/mojo_surfaces_export.h"
 
 namespace cc {
diff --git a/components/mus/public/cpp/surfaces/tests/surface_unittest.cc b/components/mus/public/cpp/surfaces/tests/surface_unittest.cc
index aa5ed1c2..2b69b62 100644
--- a/components/mus/public/cpp/surfaces/tests/surface_unittest.cc
+++ b/components/mus/public/cpp/surfaces/tests/surface_unittest.cc
@@ -21,6 +21,8 @@
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkXfermode.h"
 
+using cc::mojom::CompositorFrame;
+using cc::mojom::CompositorFramePtr;
 using cc::mojom::DebugBorderQuadState;
 using cc::mojom::DebugBorderQuadStatePtr;
 using cc::mojom::DrawQuad;
@@ -40,8 +42,6 @@
 using cc::mojom::YUVColorSpace;
 using cc::mojom::YUVVideoQuadState;
 using cc::mojom::YUVVideoQuadStatePtr;
-using mus::mojom::CompositorFrame;
-using mus::mojom::CompositorFramePtr;
 
 namespace mojo {
 namespace {
diff --git a/components/mus/public/cpp/window_surface.h b/components/mus/public/cpp/window_surface.h
index 3a9bddfd..85cd896 100644
--- a/components/mus/public/cpp/window_surface.h
+++ b/components/mus/public/cpp/window_surface.h
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "base/observer_list.h"
 #include "base/threading/thread_checker.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
+#include "components/mus/public/interfaces/surface.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_ptr_info.h"
 
@@ -35,7 +35,7 @@
   // object.
   void BindToThread();
 
-  void SubmitCompositorFrame(mojom::CompositorFramePtr frame,
+  void SubmitCompositorFrame(cc::mojom::CompositorFramePtr frame,
                              const base::Closure& callback);
 
   void set_client(WindowSurfaceClient* client) { client_ = client; }
diff --git a/components/mus/public/interfaces/BUILD.gn b/components/mus/public/interfaces/BUILD.gn
index bb10b56..8f0610b3 100644
--- a/components/mus/public/interfaces/BUILD.gn
+++ b/components/mus/public/interfaces/BUILD.gn
@@ -10,7 +10,6 @@
     "channel_handle.mojom",
     "clipboard.mojom",
     "command_buffer.mojom",
-    "compositor_frame.mojom",
     "cursor.mojom",
     "display.mojom",
     "event_matcher.mojom",
@@ -18,6 +17,7 @@
     "gpu_memory_buffer.mojom",
     "gpu_service.mojom",
     "mus_constants.mojom",
+    "surface.mojom",
     "user_access_manager.mojom",
     "window_manager.mojom",
     "window_manager_constants.mojom",
diff --git a/components/mus/public/interfaces/compositor_frame.mojom b/components/mus/public/interfaces/compositor_frame.mojom
deleted file mode 100644
index d01f829..0000000
--- a/components/mus/public/interfaces/compositor_frame.mojom
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2015 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 mus.mojom;
-
-import "cc/ipc/compositor_frame_metadata.mojom";
-import "cc/ipc/quads.mojom";
-import "cc/ipc/returned_resource.mojom";
-import "cc/ipc/transferable_resource.mojom";
-import "ui/gfx/geometry/mojo/geometry.mojom";
-import "gpu/ipc/common/mailbox_holder.mojom";
-import "gpu/ipc/common/sync_token.mojom";
-
-// See src/cc/output/compositor_frame.h.
-struct CompositorFrame {
-  cc.mojom.CompositorFrameMetadata metadata;
-  array<cc.mojom.TransferableResource> resources;
-  array<cc.mojom.RenderPass> passes;
-};
-
-// A Surface is an interface for receiving CompositorFrame structs. This is a
-// separate interface to allow CompositorFrames to be delivered from
-// supplementary (not main) threads of a mojo app.
-interface Surface {
-  // After the submitted frame is drawn for the first time, the receiver will
-  // respond to the SubmitFrame message. Clients should use this acknowledgement
-  // to ratelimit frame submissions.
-  SubmitCompositorFrame(CompositorFrame frame) => ();
-};
-
-interface SurfaceClient {
-  ReturnResources(array<cc.mojom.ReturnedResource> resources);
-};
diff --git a/components/mus/public/interfaces/gpu/OWNERS b/components/mus/public/interfaces/gpu/OWNERS
new file mode 100644
index 0000000..08850f4
--- /dev/null
+++ b/components/mus/public/interfaces/gpu/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/components/mus/public/interfaces/gpu/display_compositor.mojom b/components/mus/public/interfaces/gpu/display_compositor.mojom
index 0487bb4..f846062 100644
--- a/components/mus/public/interfaces/gpu/display_compositor.mojom
+++ b/components/mus/public/interfaces/gpu/display_compositor.mojom
@@ -4,8 +4,8 @@
 
 module mus.gpu.mojom;
 
+import "cc/ipc/compositor_frame.mojom";
 import "cc/ipc/returned_resource.mojom";
-import "components/mus/public/interfaces/compositor_frame.mojom";
 
 
 // Indicates whether the submitted CompositorFrame has been drawn to the display
@@ -46,7 +46,7 @@
   // submitted frame. Clients should use this acknowledgement to ratelimit frame
   // submissions.
   // TODO(fsamuel): We should support identifying the CF in the callback.
-  SubmitCompositorFrame(mus.mojom.CompositorFrame frame) =>
+  SubmitCompositorFrame(cc.mojom.CompositorFrame frame) =>
       (CompositorFrameDrawStatus status);
 
   // Lets the display compositor know that the client wishes to receive the next
diff --git a/components/mus/public/interfaces/surface.mojom b/components/mus/public/interfaces/surface.mojom
new file mode 100644
index 0000000..2c531d37
--- /dev/null
+++ b/components/mus/public/interfaces/surface.mojom
@@ -0,0 +1,22 @@
+// Copyright 2015 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 mus.mojom;
+
+import "cc/ipc/compositor_frame.mojom";
+import "cc/ipc/returned_resource.mojom";
+
+// A Surface is an interface for receiving CompositorFrame structs. This is a
+// separate interface to allow CompositorFrames to be delivered from
+// supplementary (not main) threads of a mojo app.
+interface Surface {
+  // After the submitted frame is drawn for the first time, the receiver will
+  // respond to the SubmitFrame message. Clients should use this acknowledgement
+  // to ratelimit frame submissions.
+  SubmitCompositorFrame(cc.mojom.CompositorFrame frame) => ();
+};
+
+interface SurfaceClient {
+  ReturnResources(array<cc.mojom.ReturnedResource> resources);
+};
diff --git a/components/mus/public/interfaces/window_tree.mojom b/components/mus/public/interfaces/window_tree.mojom
index 3313253..878b93f5 100644
--- a/components/mus/public/interfaces/window_tree.mojom
+++ b/components/mus/public/interfaces/window_tree.mojom
@@ -5,10 +5,10 @@
 module mus.mojom;
 
 import "cc/ipc/surface_id.mojom";
-import "components/mus/public/interfaces/compositor_frame.mojom";
 import "components/mus/public/interfaces/cursor.mojom";
 import "components/mus/public/interfaces/event_matcher.mojom";
 import "components/mus/public/interfaces/mus_constants.mojom";
+import "components/mus/public/interfaces/surface.mojom";
 import "components/mus/public/interfaces/window_manager.mojom";
 import "components/mus/public/interfaces/window_manager_constants.mojom";
 import "components/mus/public/interfaces/window_tree_constants.mojom";
diff --git a/components/mus/ws/server_window.h b/components/mus/ws/server_window.h
index 00ac6b55..75f4f08 100644
--- a/components/mus/ws/server_window.h
+++ b/components/mus/ws/server_window.h
@@ -14,7 +14,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
+#include "components/mus/public/interfaces/surface.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "components/mus/ws/ids.h"
 #include "components/mus/ws/server_window_surface.h"
diff --git a/components/mus/ws/server_window_surface.cc b/components/mus/ws/server_window_surface.cc
index 28d6f4e..9f19551 100644
--- a/components/mus/ws/server_window_surface.cc
+++ b/components/mus/ws/server_window_surface.cc
@@ -50,7 +50,7 @@
 }
 
 void ServerWindowSurface::SubmitCompositorFrame(
-    mojom::CompositorFramePtr frame,
+    cc::mojom::CompositorFramePtr frame,
     const SubmitCompositorFrameCallback& callback) {
   gfx::Size frame_size = frame->passes[0]->output_rect.size();
   if (!surface_id_.is_null()) {
diff --git a/components/mus/ws/server_window_surface.h b/components/mus/ws/server_window_surface.h
index 0f73a31..6467fd3 100644
--- a/components/mus/ws/server_window_surface.h
+++ b/components/mus/ws/server_window_surface.h
@@ -8,11 +8,12 @@
 #include <set>
 
 #include "base/macros.h"
+#include "cc/ipc/compositor_frame.mojom.h"
 #include "cc/surfaces/surface_factory.h"
 #include "cc/surfaces/surface_factory_client.h"
 #include "cc/surfaces/surface_id.h"
 #include "cc/surfaces/surface_id_allocator.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
+#include "components/mus/public/interfaces/surface.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "components/mus/ws/ids.h"
 #include "mojo/public/cpp/bindings/binding.h"
@@ -42,7 +43,7 @@
 
   // mojom::Surface:
   void SubmitCompositorFrame(
-      mojom::CompositorFramePtr frame,
+      cc::mojom::CompositorFramePtr frame,
       const SubmitCompositorFrameCallback& callback) override;
 
   const cc::SurfaceId& id() const { return surface_id_; }
diff --git a/components/mus/ws/server_window_surface_manager.h b/components/mus/ws/server_window_surface_manager.h
index a64b1db..1bae200 100644
--- a/components/mus/ws/server_window_surface_manager.h
+++ b/components/mus/ws/server_window_surface_manager.h
@@ -8,10 +8,10 @@
 #include <map>
 
 #include "base/macros.h"
+#include "cc/ipc/compositor_frame.mojom.h"
 #include "cc/surfaces/surface_factory.h"
 #include "cc/surfaces/surface_id.h"
 #include "cc/surfaces/surface_id_allocator.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
diff --git a/components/ntp_snippets/ntp_snippets_fetcher.cc b/components/ntp_snippets/ntp_snippets_fetcher.cc
index 96fab85..0620a5c 100644
--- a/components/ntp_snippets/ntp_snippets_fetcher.cc
+++ b/components/ntp_snippets/ntp_snippets_fetcher.cc
@@ -121,12 +121,12 @@
 
   std::string host_restriction = variations::GetVariationParamValue(
       ntp_snippets::kStudyName, kHostRestrictionName);
-  if (host_restriction == kHostRestrictionOffString) {
-    use_host_restriction_ = false;
-  } else {
+  if (host_restriction == kHostRestrictionOnString) {
     use_host_restriction_ = true;
+  } else {
+    use_host_restriction_ = false;
     LOG_IF(WARNING, !host_restriction.empty() &&
-                        host_restriction != kHostRestrictionOnString)
+                        host_restriction != kHostRestrictionOffString)
         << "Unknown value for " << kHostRestrictionName << ": "
         << host_restriction;
   }
diff --git a/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc b/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc
index 523e1d5..4ac227e5 100644
--- a/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc
+++ b/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc
@@ -325,56 +325,10 @@
               ElementsAre(base::Bucket(/*min=*/200, /*count=*/1)));
 }
 
-TEST_F(NTPSnippetsFetcherTest, ShouldReportEmptyHostsError) {
-  EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1);
-  snippets_fetcher().FetchSnippetsFromHosts(/*hosts=*/std::set<std::string>(),
-                                            /*language_code=*/"en-US",
-                                            /*count=*/1);
-  FastForwardUntilNoTasksRemain();
-  EXPECT_THAT(snippets_fetcher().last_status(),
-              Eq("Cannot fetch for empty hosts list."));
-  EXPECT_THAT(snippets_fetcher().last_json(), IsEmpty());
-  EXPECT_THAT(
-      histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"),
-      ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
-  EXPECT_THAT(histogram_tester().GetAllSamples(
-                  "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"),
-              IsEmpty());
-  // This particular error gets triggered prior to JSON parsing and hence tests
-  // observe no fetch latency.
-  EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"),
-              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1)));
-}
-
-TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) {
-  net::TestURLFetcherFactory test_url_fetcher_factory;
-  snippets_fetcher().FetchSnippetsFromHosts(
-      {"www.somehost1.com", "www.somehost2.com"}, test_lang(), /*count=*/17);
-  net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0);
-  ASSERT_THAT(fetcher, NotNull());
-  std::unique_ptr<base::Value> value =
-      base::JSONReader::Read(fetcher->upload_data());
-  ASSERT_TRUE(value) << " failed to parse JSON: "
-                     << PrintToString(fetcher->upload_data());
-  const base::DictionaryValue* dict = nullptr;
-  ASSERT_TRUE(value->GetAsDictionary(&dict));
-  const base::DictionaryValue* local_scoring_params = nullptr;
-  ASSERT_TRUE(dict->GetDictionary("advanced_options.local_scoring_params",
-                                  &local_scoring_params));
-  const base::ListValue* content_selectors = nullptr;
-  ASSERT_TRUE(
-      local_scoring_params->GetList("content_selectors", &content_selectors));
-  ASSERT_THAT(content_selectors->GetSize(), Eq(static_cast<size_t>(2)));
-  const base::DictionaryValue* content_selector = nullptr;
-  ASSERT_TRUE(content_selectors->GetDictionary(0, &content_selector));
-  std::string content_selector_value;
-  EXPECT_TRUE(content_selector->GetString("value", &content_selector_value));
-  EXPECT_THAT(content_selector_value, Eq("www.somehost1.com"));
-  ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector));
-  EXPECT_TRUE(content_selector->GetString("value", &content_selector_value));
-  EXPECT_THAT(content_selector_value, Eq("www.somehost2.com"));
-}
-
+// TODO(jkrcal) Return the tests ShouldReportEmptyHostsError and
+// ShouldRestrictToHosts once we have a way to change variation parameters from
+// unittests. The tests were tailored to previous default value of the parameter
+// fetching_host_restrict, which changed now.
 TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) {
   SetFakeResponse(/*data=*/std::string(), net::HTTP_NOT_FOUND,
                   net::URLRequestStatus::FAILED);
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
index 736d86e9..a90e574f 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -263,9 +263,9 @@
 }
 
 PageLoadTracker::~PageLoadTracker() {
-  const PageLoadExtraInfo info = GetPageLoadMetricsInfo();
-  if (!info.time_to_commit.is_zero() && renderer_tracked() &&
-      timing_.IsEmpty()) {
+  const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
+
+  if (info.time_to_commit && renderer_tracked() && timing_.IsEmpty()) {
     RecordInternalError(ERR_NO_IPCS_RECEIVED);
   }
   // Recall that trackers that are given ABORT_UNKNOWN_NAVIGATION have their
@@ -332,6 +332,7 @@
     // foregrounded.
     DCHECK_EQ(started_in_foreground_, foreground_time_.is_null());
     background_time_ = base::TimeTicks::Now();
+    ClampBrowserTimestampIfInterProcessTimeTickSkew(&background_time_);
   }
 
   for (const auto& observer : observers_)
@@ -346,6 +347,7 @@
     // backgrounded.
     DCHECK_NE(started_in_foreground_, background_time_.is_null());
     foreground_time_ = base::TimeTicks::Now();
+    ClampBrowserTimestampIfInterProcessTimeTickSkew(&foreground_time_);
   }
 
   for (const auto& observer : observers_)
@@ -356,6 +358,7 @@
   // TODO(bmcquade): To improve accuracy, consider adding commit time to
   // NavigationHandle. Taking a timestamp here should be close enough for now.
   commit_time_ = base::TimeTicks::Now();
+  ClampBrowserTimestampIfInterProcessTimeTickSkew(&commit_time_);
   url_ = navigation_handle->GetURL();
   for (const auto& observer : observers_) {
     observer->OnCommit(navigation_handle);
@@ -408,7 +411,7 @@
 
     const PageLoadMetadata last_metadata = metadata_;
     metadata_ = new_metadata;
-    const PageLoadExtraInfo info = GetPageLoadMetricsInfo();
+    const PageLoadExtraInfo info = ComputePageLoadExtraInfo();
     for (const auto& observer : observers_) {
       DispatchObserverTimingCallbacks(observer.get(), last_timing, new_timing,
                                       last_metadata, info);
@@ -427,28 +430,61 @@
   observers_.push_back(std::move(observer));
 }
 
-PageLoadExtraInfo PageLoadTracker::GetPageLoadMetricsInfo() {
-  base::TimeDelta first_background_time;
-  base::TimeDelta first_foreground_time;
-  base::TimeDelta time_to_abort;
-  base::TimeDelta time_to_commit;
-  if (!background_time_.is_null())
+void PageLoadTracker::ClampBrowserTimestampIfInterProcessTimeTickSkew(
+    base::TimeTicks* event_time) {
+  DCHECK(event_time != nullptr);
+  // Windows 10 GCE bot non-deterministically failed because TimeTicks::Now()
+  // called in the browser process e.g. commit_time was less than
+  // navigation_start_ that was populated in the renderer process because the
+  // clock was not system-wide monotonic.
+  // Note that navigation_start_ can also be set in the browser process in
+  // some cases and in those cases event_time should never be <
+  // navigation_start_. If it is due to a code error and it gets clamped in this
+  // function, on high resolution systems it should lead to a dcheck failure.
+
+  // TODO (shivanisha) Currently IsHighResolution is the best way to check
+  // if the clock is system-wide monotonic. However IsHighResolution
+  // does a broader check to see if the clock in use is high resolution
+  // which also implies it is system-wide monotonic (on Windows).
+  if (base::TimeTicks::IsHighResolution()) {
+    DCHECK(event_time->is_null() || *event_time >= navigation_start_);
+    return;
+  }
+
+  if (!event_time->is_null() && *event_time < navigation_start_) {
+    RecordInternalError(ERR_INTER_PROCESS_TIME_TICK_SKEW);
+    *event_time = navigation_start_;
+  }
+}
+
+PageLoadExtraInfo PageLoadTracker::ComputePageLoadExtraInfo() {
+  base::Optional<base::TimeDelta> first_background_time;
+  base::Optional<base::TimeDelta> first_foreground_time;
+  base::Optional<base::TimeDelta> time_to_abort;
+  base::Optional<base::TimeDelta> time_to_commit;
+
+  if (!background_time_.is_null()) {
+    DCHECK_GE(background_time_, navigation_start_);
     first_background_time = background_time_ - navigation_start_;
-  if (!foreground_time_.is_null())
+  }
+
+  if (!foreground_time_.is_null()) {
+    DCHECK_GE(foreground_time_, navigation_start_);
     first_foreground_time = foreground_time_ - navigation_start_;
+  }
+
   if (abort_type_ != ABORT_NONE) {
-    DCHECK_GT(abort_time_, navigation_start_);
+    DCHECK_GE(abort_time_, navigation_start_);
     time_to_abort = abort_time_ - navigation_start_;
   } else {
     DCHECK(abort_time_.is_null());
   }
 
   if (!commit_time_.is_null()) {
-    DCHECK_GT(commit_time_, navigation_start_);
+    DCHECK_GE(commit_time_, navigation_start_);
     time_to_commit = commit_time_ - navigation_start_;
-  } else {
-    DCHECK(commit_time_.is_null());
   }
+
   return PageLoadExtraInfo(
       first_background_time, first_foreground_time, started_in_foreground_,
       commit_time_.is_null() ? GURL() : url_, time_to_commit, abort_type_,
@@ -456,17 +492,19 @@
 }
 
 void PageLoadTracker::NotifyAbort(UserAbortType abort_type,
-                                  base::TimeTicks timestamp) {
+                                  base::TimeTicks timestamp,
+                                  bool is_certainly_browser_timestamp) {
   DCHECK_NE(abort_type, ABORT_NONE);
   // Use UpdateAbort to update an already notified PageLoadTracker.
   if (abort_type_ != ABORT_NONE)
     return;
 
-  UpdateAbortInternal(abort_type, timestamp);
+  UpdateAbortInternal(abort_type, timestamp, is_certainly_browser_timestamp);
 }
 
 void PageLoadTracker::UpdateAbort(UserAbortType abort_type,
-                                  base::TimeTicks timestamp) {
+                                  base::TimeTicks timestamp,
+                                  bool is_certainly_browser_timestamp) {
   DCHECK_NE(abort_type, ABORT_NONE);
   DCHECK_NE(abort_type, ABORT_OTHER);
   DCHECK_EQ(abort_type_, ABORT_OTHER);
@@ -474,7 +512,8 @@
   // For some aborts (e.g. navigations), the initiated timestamp can be earlier
   // than the timestamp that aborted the load. Taking the minimum gives the
   // closest user initiated time known.
-  UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp));
+  UpdateAbortInternal(abort_type, std::min(abort_time_, timestamp),
+                      is_certainly_browser_timestamp);
 }
 
 bool PageLoadTracker::IsLikelyProvisionalAbort(
@@ -493,7 +532,8 @@
 }
 
 void PageLoadTracker::UpdateAbortInternal(UserAbortType abort_type,
-                                          base::TimeTicks timestamp) {
+                                          base::TimeTicks timestamp,
+                                          bool is_certainly_browser_timestamp) {
   // When a provisional navigation commits, that navigation's start time is
   // interpreted as the abort time for other provisional loads in the tab.
   // However, this only makes sense if the committed load started after the
@@ -503,7 +543,7 @@
   // infer the cause of aborts. It would be better if the navigation code could
   // instead report the actual cause of an aborted navigation. See crbug/571647
   // for details.
-  if (timestamp <= navigation_start_) {
+  if (timestamp < navigation_start_) {
     RecordInternalError(ERR_ABORT_BEFORE_NAVIGATION_START);
     abort_type_ = ABORT_NONE;
     abort_time_ = base::TimeTicks();
@@ -511,6 +551,10 @@
   }
   abort_type_ = abort_type;
   abort_time_ = timestamp;
+
+  if (is_certainly_browser_timestamp) {
+    ClampBrowserTimestampIfInterProcessTimeTickSkew(&abort_time_);
+  }
 }
 
 // static
@@ -627,6 +671,12 @@
           navigation_handle, chain_size, chain_size_same_url))));
 }
 
+const PageLoadExtraInfo
+MetricsWebContentsObserver::GetPageLoadExtraInfoForCommittedLoad() {
+  DCHECK(committed_load_);
+  return committed_load_->ComputePageLoadExtraInfo();
+}
+
 void MetricsWebContentsObserver::DidFinishNavigation(
     content::NavigationHandle* navigation_handle) {
   if (!navigation_handle->IsInMainFrame())
@@ -659,7 +709,7 @@
     // Note that this can come from some non user-initiated errors, such as
     // downloads, or 204 responses. See crbug.com/542369.
     if ((error == net::OK) || (error == net::ERR_ABORTED)) {
-      finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now());
+      finished_nav->NotifyAbort(ABORT_OTHER, base::TimeTicks::Now(), true);
       aborted_provisional_loads_.push_back(std::move(finished_nav));
     }
 
@@ -675,9 +725,11 @@
   // lose data on provisional loads that were aborted by other provisional
   // loads. Those will either be listed as ABORT_OTHER or as being aborted by
   // this load.
+  // is_certainly_browser_timestamp is set to false because NavigationStart()
+  // could be set in either the renderer or browser process.
   NotifyAbortAllLoadsWithTimestamp(
       AbortTypeForPageTransition(navigation_handle->GetPageTransition()),
-      navigation_handle->NavigationStart());
+      navigation_handle->NavigationStart(), false);
 
   committed_load_ = std::move(finished_nav);
   aborted_provisional_loads_.clear();
@@ -764,20 +816,24 @@
 }
 
 void MetricsWebContentsObserver::NotifyAbortAllLoads(UserAbortType abort_type) {
-  NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now());
+  NotifyAbortAllLoadsWithTimestamp(abort_type, base::TimeTicks::Now(), true);
 }
 
 void MetricsWebContentsObserver::NotifyAbortAllLoadsWithTimestamp(
     UserAbortType abort_type,
-    base::TimeTicks timestamp) {
+    base::TimeTicks timestamp,
+    bool is_certainly_browser_timestamp) {
   if (committed_load_)
-    committed_load_->NotifyAbort(abort_type, timestamp);
+    committed_load_->NotifyAbort(abort_type, timestamp,
+                                 is_certainly_browser_timestamp);
   for (const auto& kv : provisional_loads_) {
-    kv.second->NotifyAbort(abort_type, timestamp);
+    kv.second->NotifyAbort(abort_type, timestamp,
+                           is_certainly_browser_timestamp);
   }
   for (const auto& tracker : aborted_provisional_loads_) {
     if (tracker->IsLikelyProvisionalAbort(timestamp))
-      tracker->UpdateAbort(abort_type, timestamp);
+      tracker->UpdateAbort(abort_type, timestamp,
+                           is_certainly_browser_timestamp);
   }
   aborted_provisional_loads_.clear();
 }
@@ -799,7 +855,7 @@
 
   base::TimeTicks timestamp = new_navigation->NavigationStart();
   if (last_aborted_load->IsLikelyProvisionalAbort(timestamp))
-    last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp);
+    last_aborted_load->UpdateAbort(ABORT_UNKNOWN_NAVIGATION, timestamp, false);
 
   aborted_provisional_loads_.clear();
   return last_aborted_load;
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h
index 291958a2..dee13cb 100644
--- a/components/page_load_metrics/browser/metrics_web_contents_observer.h
+++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -92,6 +92,11 @@
   // Receives user input before navigation start
   ERR_USER_INPUT_WITH_NO_RELEVANT_LOAD,
 
+  // A TimeTicks value in the browser process has value less than
+  // navigation_start_. This could happen if navigation_start_ was computed in
+  // renderer process and the system clock has inter process time tick skew.
+  ERR_INTER_PROCESS_TIME_TICK_SKEW,
+
   // Add values before this final count.
   ERR_LAST_ENTRY,
 };
@@ -150,8 +155,16 @@
   // If the user performs some abort-like action while we are tracking this page
   // load, notify the tracker. Note that we may not classify this as an abort if
   // we've already performed a first paint.
-  void NotifyAbort(UserAbortType abort_type, base::TimeTicks timestamp);
-  void UpdateAbort(UserAbortType abort_type, base::TimeTicks timestamp);
+  // is_certainly_browser_timestamp signifies if the timestamp passed is taken
+  // in the
+  // browser process or not. We need this to possibly clamp browser timestamp on
+  // a machine with inter process time tick skew.
+  void NotifyAbort(UserAbortType abort_type,
+                   base::TimeTicks timestamp,
+                   bool is_certainly_browser_timestamp);
+  void UpdateAbort(UserAbortType abort_type,
+                   base::TimeTicks timestamp,
+                   bool is_certainly_browser_timestamp);
 
   // This method returns true if this page load has been aborted with type of
   // ABORT_OTHER, and the |abort_cause_time| is within a sufficiently close
@@ -168,11 +181,20 @@
     return url_;
   }
 
+  PageLoadExtraInfo ComputePageLoadExtraInfo();
+
  private:
-  PageLoadExtraInfo GetPageLoadMetricsInfo();
+  // This function converts a TimeTicks value taken in the browser process
+  // to navigation_start_ if:
+  // - base::TimeTicks is not comparable across processes because the clock
+  // is not system wide monotonic.
+  // - *event_time < navigation_start_
+  void ClampBrowserTimestampIfInterProcessTimeTickSkew(
+      base::TimeTicks* event_time);
 
   void UpdateAbortInternal(UserAbortType abort_type,
-                           base::TimeTicks timestamp);
+                           base::TimeTicks timestamp,
+                           bool is_certainly_browser_timestamp);
 
   // If |final_navigation| is null, then this is an "unparented" abort chain,
   // and represents a sequence of provisional aborts that never ends with a
@@ -262,6 +284,9 @@
   void RenderViewHostChanged(content::RenderViewHost* old_host,
                              content::RenderViewHost* new_host) override;
 
+  // This getter function is required for testing.
+  const PageLoadExtraInfo GetPageLoadExtraInfoForCommittedLoad();
+
  private:
   friend class content::WebContentsUserData<MetricsWebContentsObserver>;
 
@@ -269,7 +294,8 @@
   // that might abort them.
   void NotifyAbortAllLoads(UserAbortType abort_type);
   void NotifyAbortAllLoadsWithTimestamp(UserAbortType abort_type,
-                                        base::TimeTicks timestamp);
+                                        base::TimeTicks timestamp,
+                                        bool is_certainly_browser_timestamp);
 
   // Register / Unregister input event callback to given RenderViewHost
   void RegisterInputEventObserver(content::RenderViewHost* host);
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer.cc b/components/page_load_metrics/browser/page_load_metrics_observer.cc
index 68de4d4..98ffef5 100644
--- a/components/page_load_metrics/browser/page_load_metrics_observer.cc
+++ b/components/page_load_metrics/browser/page_load_metrics_observer.cc
@@ -6,14 +6,15 @@
 
 namespace page_load_metrics {
 
-PageLoadExtraInfo::PageLoadExtraInfo(base::TimeDelta first_background_time,
-                                     base::TimeDelta first_foreground_time,
-                                     bool started_in_foreground,
-                                     const GURL& committed_url,
-                                     base::TimeDelta time_to_commit,
-                                     UserAbortType abort_type,
-                                     base::TimeDelta time_to_abort,
-                                     const PageLoadMetadata& metadata)
+PageLoadExtraInfo::PageLoadExtraInfo(
+    const base::Optional<base::TimeDelta>& first_background_time,
+    const base::Optional<base::TimeDelta>& first_foreground_time,
+    bool started_in_foreground,
+    const GURL& committed_url,
+    const base::Optional<base::TimeDelta>& time_to_commit,
+    UserAbortType abort_type,
+    const base::Optional<base::TimeDelta>& time_to_abort,
+    const PageLoadMetadata& metadata)
     : first_background_time(first_background_time),
       first_foreground_time(first_foreground_time),
       started_in_foreground(started_in_foreground),
@@ -25,4 +26,5 @@
 
 PageLoadExtraInfo::PageLoadExtraInfo(const PageLoadExtraInfo& other) = default;
 
+PageLoadExtraInfo::~PageLoadExtraInfo() {}
 }  // namespace page_load_metrics
diff --git a/components/page_load_metrics/browser/page_load_metrics_observer.h b/components/page_load_metrics/browser/page_load_metrics_observer.h
index a08ec0a..3b486dc 100644
--- a/components/page_load_metrics/browser/page_load_metrics_observer.h
+++ b/components/page_load_metrics/browser/page_load_metrics_observer.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_OBSERVER_H_
 
 #include "base/macros.h"
+#include "base/optional.h"
 #include "components/page_load_metrics/common/page_load_timing.h"
 #include "content/public/browser/navigation_handle.h"
 #include "third_party/WebKit/public/web/WebInputEvent.h"
@@ -50,23 +51,25 @@
 };
 
 struct PageLoadExtraInfo {
-  PageLoadExtraInfo(base::TimeDelta first_background_time,
-                    base::TimeDelta first_foreground_time,
-                    bool started_in_foreground,
-                    const GURL& committed_url,
-                    base::TimeDelta time_to_commit,
-                    UserAbortType abort_type,
-                    base::TimeDelta time_to_abort,
-                    const PageLoadMetadata& metadata);
+  PageLoadExtraInfo(
+      const base::Optional<base::TimeDelta>& first_background_time,
+      const base::Optional<base::TimeDelta>& first_foreground_time,
+      bool started_in_foreground,
+      const GURL& committed_url,
+      const base::Optional<base::TimeDelta>& time_to_commit,
+      UserAbortType abort_type,
+      const base::Optional<base::TimeDelta>& time_to_abort,
+      const PageLoadMetadata& metadata);
+
   PageLoadExtraInfo(const PageLoadExtraInfo& other);
 
+  ~PageLoadExtraInfo();
+
   // The first time that the page was backgrounded since the navigation started.
-  // If the page has not been backgrounded this will be base::TimeDelta().
-  const base::TimeDelta first_background_time;
+  const base::Optional<base::TimeDelta> first_background_time;
 
   // The first time that the page was foregrounded since the navigation started.
-  // If the page has not been foregrounded this will be base::TimeDelta().
-  const base::TimeDelta first_foreground_time;
+  const base::Optional<base::TimeDelta> first_foreground_time;
 
   // True if the page load started in the foreground.
   const bool started_in_foreground;
@@ -75,15 +78,13 @@
   // empty.
   const GURL committed_url;
 
-  // Time from navigation start until commit. If the page load did not commit,
-  // |time_to_commit| will be zero.
-  const base::TimeDelta time_to_commit;
+  // Time from navigation start until commit.
+  const base::Optional<base::TimeDelta> time_to_commit;
 
   // The abort time and time to abort for this page load. If the page was not
-  // aborted, |abort_type| will be |ABORT_NONE| and |time_to_abort| will be
-  // |base::TimeDelta()|.
+  // aborted, |abort_type| will be |ABORT_NONE|.
   const UserAbortType abort_type;
-  const base::TimeDelta time_to_abort;
+  const base::Optional<base::TimeDelta> time_to_abort;
 
   // Extra information supplied to the page load metrics system from the
   // renderer.
diff --git a/components/page_load_metrics/browser/page_load_metrics_util.cc b/components/page_load_metrics/browser/page_load_metrics_util.cc
index a9ead77..96217bf 100644
--- a/components/page_load_metrics/browser/page_load_metrics_util.cc
+++ b/components/page_load_metrics/browser/page_load_metrics_util.cc
@@ -14,8 +14,19 @@
 bool WasStartedInForegroundEventInForeground(base::TimeDelta event,
                                              const PageLoadExtraInfo& info) {
   return info.started_in_foreground && !event.is_zero() &&
-         (info.first_background_time.is_zero() ||
-          event < info.first_background_time);
+         (!info.first_background_time ||
+          event <= info.first_background_time.value());
+}
+
+// TODO (shivanisha) The above function is used for TimeDeltas coming over IPC.
+// Merge these two when page_load_metrics only handles Optional TimeDelta
+// values in the browser process.
+bool WasStartedInForegroundOptionalEventInForeground(
+    const base::Optional<base::TimeDelta>& event,
+    const PageLoadExtraInfo& info) {
+  return info.started_in_foreground && event &&
+         (!info.first_background_time ||
+          event.value() <= info.first_background_time.value());
 }
 
 bool WasParseInForeground(base::TimeDelta parse_start,
@@ -24,9 +35,9 @@
   if (parse_start.is_zero()) {
     return false;
   }
-  const bool incomplete_parse_in_foreground =
-      parse_stop.is_zero() && info.started_in_foreground &&
-      info.first_background_time.is_zero();
+  const bool incomplete_parse_in_foreground = parse_stop.is_zero() &&
+                                              info.started_in_foreground &&
+                                              !info.first_background_time;
 
   return incomplete_parse_in_foreground ||
          WasStartedInForegroundEventInForeground(parse_stop, info);
diff --git a/components/page_load_metrics/browser/page_load_metrics_util.h b/components/page_load_metrics/browser/page_load_metrics_util.h
index c79612e2..66dc3aa 100644
--- a/components/page_load_metrics/browser/page_load_metrics_util.h
+++ b/components/page_load_metrics/browser/page_load_metrics_util.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_UTIL_H_
 
 #include "base/metrics/histogram_macros.h"
+#include "base/optional.h"
 #include "base/time/time.h"
 
 #define PAGE_LOAD_HISTOGRAM(name, sample)                           \
@@ -25,9 +26,16 @@
 // When a page is backgrounded, some events (e.g. paint) are delayed. Since
 // these data points can skew the mean, they should not be mixed with timing
 // events that occurred in the foreground.
+// If the event time delta and background time delta are equal, we still
+// consider the event to be logged in the foreground histogram since any
+// background specific handling would not yet have been applied to that event.
 bool WasStartedInForegroundEventInForeground(base::TimeDelta event,
                                              const PageLoadExtraInfo& info);
 
+bool WasStartedInForegroundOptionalEventInForeground(
+    const base::Optional<base::TimeDelta>& event,
+    const PageLoadExtraInfo& info);
+
 // Returns true if:
 // - Parse started and did not complete but the entire page load duration
 // happened in the foreground.
@@ -35,7 +43,6 @@
 bool WasParseInForeground(base::TimeDelta parse_start,
                           base::TimeDelta parse_stop,
                           const PageLoadExtraInfo& info);
-
 }  // namespace page_load_metrics
 
 #endif  // COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_UTIL_H_
diff --git a/components/page_load_metrics/common/page_load_timing.h b/components/page_load_metrics/common/page_load_timing.h
index 4cbe9fa..a61551d 100644
--- a/components/page_load_metrics/common/page_load_timing.h
+++ b/components/page_load_metrics/common/page_load_timing.h
@@ -28,6 +28,12 @@
 
   // All TimeDeltas are relative to navigation_start
 
+  // TODO(shivanisha): Issue 596367 shows that it is possible for a valid
+  // TimeDelta value to be 0 (2 TimeTicks can have the same value even if they
+  // were assigned in separate instructions if the clock speed is less
+  // granular). The solution there was to use base::Optional for those values.
+  // Consider changing the below values to Optional as well.
+
   // Time that the first byte of the response is received.
   base::TimeDelta response_start;
 
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index 15b406fe..0a77694 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -136,6 +136,11 @@
       client_->GetLogManager()->IsLoggingActive()));
 }
 
+void ContentPasswordManagerDriver::AllowToRunFormClassifier() {
+  render_frame_host_->Send(new AutofillMsg_AllowToRunFormClassifier(
+      render_frame_host_->GetRoutingID()));
+}
+
 PasswordGenerationManager*
 ContentPasswordManagerDriver::GetPasswordGenerationManager() {
   return &password_generation_manager_;
@@ -194,6 +199,7 @@
 void ContentPasswordManagerDriver::OnPasswordFormsParsedNoRenderCheck(
     const std::vector<autofill::PasswordForm>& forms) {
   GetPasswordManager()->OnPasswordFormsParsed(this, forms);
+  GetPasswordGenerationManager()->CheckIfFormClassifierShouldRun();
 }
 
 void ContentPasswordManagerDriver::OnPasswordFormsRendered(
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h
index 0315a01e..28678cb6 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.h
+++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -71,6 +71,7 @@
   void ForceSavePassword() override;
   void GeneratePassword() override;
   void SendLoggingAvailability() override;
+  void AllowToRunFormClassifier() override;
 
   PasswordGenerationManager* GetPasswordGenerationManager() override;
   PasswordManager* GetPasswordManager() override;
diff --git a/components/password_manager/core/browser/password_generation_manager.cc b/components/password_manager/core/browser/password_generation_manager.cc
index 637abde..d1b36412 100644
--- a/components/password_manager/core/browser/password_generation_manager.cc
+++ b/components/password_manager/core/browser/password_generation_manager.cc
@@ -71,4 +71,9 @@
   return true;
 }
 
+void PasswordGenerationManager::CheckIfFormClassifierShouldRun() {
+  if (autofill::FormStructure::IsAutofillFieldMetadataEnabled())
+    driver_->AllowToRunFormClassifier();
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_generation_manager.h b/components/password_manager/core/browser/password_generation_manager.h
index 6f2fe47..c683b18 100644
--- a/components/password_manager/core/browser/password_generation_manager.h
+++ b/components/password_manager/core/browser/password_generation_manager.h
@@ -46,6 +46,12 @@
   // Determines current state of password generation
   bool IsGenerationEnabled() const;
 
+  // Determine if the form classifier should run. If yes, sends a message to the
+  // renderer.
+  // TODO(crbug.com/621442): Remove client-side form classifier when server-side
+  // classifier is ready.
+  void CheckIfFormClassifierShouldRun();
+
  private:
   friend class PasswordGenerationManagerTest;
 
diff --git a/components/password_manager/core/browser/password_generation_manager_unittest.cc b/components/password_manager/core/browser/password_generation_manager_unittest.cc
index 6bcc8a6b..5a3aedc 100644
--- a/components/password_manager/core/browser/password_generation_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_generation_manager_unittest.cc
@@ -4,10 +4,12 @@
 
 #include "components/password_manager/core/browser/password_generation_manager.h"
 
+#include <memory>
 #include <utility>
 #include <vector>
 
 #include "base/message_loop/message_loop.h"
+#include "base/metrics/field_trial.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/autofill_metrics.h"
@@ -24,6 +26,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/testing_pref_service.h"
+#include "components/variations/entropy_provider.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -63,6 +66,8 @@
     return found_forms_eligible_for_generation_;
   }
 
+  MOCK_METHOD0(AllowToRunFormClassifier, void());
+
  private:
   PasswordManager password_manager_;
   PasswordGenerationManager password_generation_manager_;
@@ -258,4 +263,23 @@
   EXPECT_FALSE(IsGenerationEnabled());
 }
 
+TEST_F(PasswordGenerationManagerTest, CheckIfFormClassifierShouldRun) {
+  const bool kFalseTrue[] = {false, true};
+  for (bool is_autofill_field_metadata_enabled : kFalseTrue) {
+    SCOPED_TRACE(testing::Message() << "is_autofill_field_metadata_enabled="
+                                    << is_autofill_field_metadata_enabled);
+    std::unique_ptr<base::FieldTrialList> field_trial_list;
+    scoped_refptr<base::FieldTrial> field_trial;
+    if (is_autofill_field_metadata_enabled) {
+      field_trial_list.reset(
+          new base::FieldTrialList(new metrics::SHA1EntropyProvider("foo")));
+      field_trial = base::FieldTrialList::CreateFieldTrial(
+          "AutofillFieldMetadata", "Enabled");
+      EXPECT_CALL(*GetTestDriver(), AllowToRunFormClassifier())
+          .WillOnce(testing::Return());
+    }
+    GetGenerationManager()->CheckIfFormClassifierShouldRun();
+  }
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_driver.h b/components/password_manager/core/browser/password_manager_driver.h
index 607d9ce..be5723c 100644
--- a/components/password_manager/core/browser/password_manager_driver.h
+++ b/components/password_manager/core/browser/password_manager_driver.h
@@ -96,6 +96,9 @@
   // chrome://password-manager-internals is available.
   virtual void SendLoggingAvailability() {}
 
+  // Allows the form classifier to find generation fields.
+  virtual void AllowToRunFormClassifier() {}
+
  private:
   DISALLOW_COPY_AND_ASSIGN(PasswordManagerDriver);
 };
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 75582b6..50a03e4 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -3046,6 +3046,8 @@
           'tags': ['website-sharing'],
           'desc': '''Allows you to set whether websites are allowed to track the users' physical location. Tracking the users' physical location can be allowed by default, denied by default or the user can be asked every time a website requests the physical location.
 
+          If this policy is set to 'BlockGeolocation', location sharing is disallowed for ARC apps.
+
           If this policy is left not set, 'AskGeolocation' will be used and the user will be able to change it.''',
         },
         {
@@ -5627,6 +5629,7 @@
 
       When this policy is disabled, the user will never be prompted and audio
       capture only be available to URLs configured in AudioCaptureAllowedUrls.
+      For ARC apps, the microphone is permanently muted.
 
       This policy affects all types of audio inputs and not only the built-in microphone.''',
     },
@@ -5670,12 +5673,12 @@
       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.
-      ARC-apps will be able to access the camera if they have been given
+      ARC apps will be able to access the camera if they have been given
       permission.
 
       When this policy is disabled, the user will never be prompted and video
       capture only be available to URLs configured in VideoCaptureAllowedUrls.
-      ARC-apps will not be able to access the camera.
+      ARC apps will not be able to access the camera.
 
       Outside of ARC-apps, this policy affects all types of video inputs and
       not only the built-in camera.''',
@@ -5718,6 +5721,7 @@
       'desc': '''Disables taking screenshots.
 
       If enabled screenshots cannot be taken using keyboard shortcuts or extension APIs.
+      Additionally, screen capture is disabled for ARC apps.
 
       If disabled or not specified, taking screenshots is allowed.'''
     },
diff --git a/components/printing/common/OWNERS b/components/printing/common/OWNERS
index 52cd5d0..9216e7a 100644
--- a/components/printing/common/OWNERS
+++ b/components/printing/common/OWNERS
@@ -1,5 +1,5 @@
-per-file *messages*.h=set noparent
-per-file *messages*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
 
 per-file *_param_traits*.*=set noparent
 per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/components/safe_json/safe_json_parser_impl.cc b/components/safe_json/safe_json_parser_impl.cc
index d2ec950..6d474615 100644
--- a/components/safe_json/safe_json_parser_impl.cc
+++ b/components/safe_json/safe_json_parser_impl.cc
@@ -38,10 +38,10 @@
   DCHECK(io_thread_checker_.CalledOnValidThread());
   mojo_json_parser_.reset(
       new content::UtilityProcessMojoClient<mojom::SafeJsonParser>(
-          l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_JSON_PARSER_NAME),
-          base::Bind(&SafeJsonParserImpl::OnConnectionError,
-                     base::Unretained(this))));
+          l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_JSON_PARSER_NAME)));
 
+  mojo_json_parser_->set_error_callback(base::Bind(
+      &SafeJsonParserImpl::OnConnectionError, base::Unretained(this)));
   mojo_json_parser_->Start();
 
   mojo_json_parser_->service()->Parse(
diff --git a/components/search_provider_logos/google_logo_api.cc b/components/search_provider_logos/google_logo_api.cc
index d97966f..02c127d 100644
--- a/components/search_provider_logos/google_logo_api.cc
+++ b/components/search_provider_logos/google_logo_api.cc
@@ -43,8 +43,10 @@
     if (wants_cta)
       params.push_back("cta:1");
 
-    if (transparent)
+    if (transparent) {
       params.push_back("transp:1");
+      params.push_back("graybg:1");
+    }
 
     query += base::JoinString(params, ",");
     GURL::Replacements replacements;
diff --git a/components/search_provider_logos/logo_tracker_unittest.cc b/components/search_provider_logos/logo_tracker_unittest.cc
index 0370ba2..00fd281 100644
--- a/components/search_provider_logos/logo_tracker_unittest.cc
+++ b/components/search_provider_logos/logo_tracker_unittest.cc
@@ -432,12 +432,14 @@
 TEST_F(LogoTrackerTest, CTATransparentHasCommas) {
   GURL url_with_fp = GoogleAppendQueryparamsToLogoURL(
       GURL("http://logourl.com/path"), "abc123", true, true);
-  EXPECT_EQ("http://logourl.com/path?async=es_dfp:abc123,cta:1,transp:1",
-            url_with_fp.spec());
+  EXPECT_EQ(
+      "http://logourl.com/path?async=es_dfp:abc123,cta:1,transp:1,graybg:1",
+      url_with_fp.spec());
 
   url_with_fp = GoogleAppendQueryparamsToLogoURL(
       GURL("http://logourl.com/?a=b"), "", true, true);
-  EXPECT_EQ("http://logourl.com/?a=b&async=cta:1,transp:1", url_with_fp.spec());
+  EXPECT_EQ("http://logourl.com/?a=b&async=cta:1,transp:1,graybg:1",
+            url_with_fp.spec());
 }
 
 TEST_F(LogoTrackerTest, DownloadAndCacheLogo) {
diff --git a/components/subresource_filter.gypi b/components/subresource_filter.gypi
index 00c55cc..2d9b72fd 100644
--- a/components/subresource_filter.gypi
+++ b/components/subresource_filter.gypi
@@ -61,6 +61,8 @@
         # Note: sources list duplicated in GN build.
         'subresource_filter/core/common/activation_state.cc',
         'subresource_filter/core/common/activation_state.h',
+        'subresource_filter/core/common/memory_mapped_ruleset.cc',
+        'subresource_filter/core/common/memory_mapped_ruleset.h',
       ],
     },
   ],
@@ -94,6 +96,7 @@
             '../base/base.gyp:base',
             '../content/content.gyp:content_common',
             '../content/content.gyp:content_renderer',
+            '../ipc/ipc.gyp:ipc',
             'subresource_filter_content_common',
             'subresource_filter_core_common',
           ],
@@ -102,6 +105,8 @@
           ],
           'sources': [
             # Note: sources list duplicated in GN build.
+            'subresource_filter/content/renderer/ruleset_dealer.cc',
+            'subresource_filter/content/renderer/ruleset_dealer.h',
             'subresource_filter/content/renderer/subresource_filter_agent.cc',
             'subresource_filter/content/renderer/subresource_filter_agent.h',
           ],
@@ -114,6 +119,7 @@
             '../base/base.gyp:base',
             '../content/content.gyp:content_browser',
             '../content/content.gyp:content_common',
+            '../ipc/ipc.gyp:ipc',
             'subresource_filter_content_common',
             'subresource_filter_core_browser',
             'subresource_filter_core_common',
@@ -124,6 +130,8 @@
           ],
           'sources': [
             # Note: sources list duplicated in GN build.
+            'subresource_filter/content/browser/content_ruleset_distributor.cc',
+            'subresource_filter/content/browser/content_ruleset_distributor.h',
             'subresource_filter/content/browser/content_subresource_filter_driver.cc',
             'subresource_filter/content/browser/content_subresource_filter_driver.h',
             'subresource_filter/content/browser/content_subresource_filter_driver_factory.cc',
diff --git a/components/subresource_filter/content/browser/BUILD.gn b/components/subresource_filter/content/browser/BUILD.gn
index 0a8f2cb8..fdd5dff 100644
--- a/components/subresource_filter/content/browser/BUILD.gn
+++ b/components/subresource_filter/content/browser/BUILD.gn
@@ -4,6 +4,8 @@
 
 source_set("browser") {
   sources = [
+    "content_ruleset_distributor.cc",
+    "content_ruleset_distributor.h",
     "content_subresource_filter_driver.cc",
     "content_subresource_filter_driver.h",
     "content_subresource_filter_driver_factory.cc",
@@ -16,6 +18,23 @@
     "//components/subresource_filter/core/common",
     "//content/public/browser",
     "//content/public/common",
+    "//ipc",
     "//url",
   ]
 }
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "content_ruleset_distributor_unittest.cc",
+  ]
+  deps = [
+    ":browser",
+    "//base/test:test_support",
+    "//components/subresource_filter/content/common",
+    "//content/test:test_support",
+    "//ipc",
+    "//ipc:test_support",
+    "//testing/gtest",
+  ]
+}
diff --git a/components/subresource_filter/content/browser/content_ruleset_distributor.cc b/components/subresource_filter/content/browser/content_ruleset_distributor.cc
new file mode 100644
index 0000000..d77db191
--- /dev/null
+++ b/components/subresource_filter/content/browser/content_ruleset_distributor.cc
@@ -0,0 +1,73 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/subresource_filter/content/browser/content_ruleset_distributor.h"
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "components/subresource_filter/content/common/subresource_filter_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host.h"
+#include "ipc/ipc_platform_file.h"
+
+namespace subresource_filter {
+
+namespace {
+
+void SendRulesetToRenderProcess(base::File* file,
+                                content::RenderProcessHost* rph) {
+  DCHECK(rph);
+  DCHECK(file);
+  DCHECK(file->IsValid());
+  rph->Send(new SubresourceFilterMsg_SetRulesetForProcess(
+      IPC::TakePlatformFileForTransit(file->Duplicate())));
+}
+
+// The file handle is closed when the argument goes out of scope.
+void FileCloser(base::File) {}
+
+}  // namespace
+
+ContentRulesetDistributor::ContentRulesetDistributor() {
+  // Must rely on notifications as RenderProcessHostObserver::RenderProcessReady
+  // would only be called after queued IPC messages (potentially triggering a
+  // navigation) had already been sent to the new renderer.
+  notification_registrar_.Add(
+      this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+      content::NotificationService::AllBrowserContextsAndSources());
+}
+
+ContentRulesetDistributor::~ContentRulesetDistributor() {
+  content::BrowserThread::PostTask(
+      content::BrowserThread::FILE, FROM_HERE,
+      base::Bind(&FileCloser, base::Passed(&ruleset_data_)));
+}
+
+void ContentRulesetDistributor::PublishNewVersion(base::File ruleset_data) {
+  DCHECK(ruleset_data.IsValid());
+  ruleset_data_ = std::move(ruleset_data);
+  for (auto it = content::RenderProcessHost::AllHostsIterator(); !it.IsAtEnd();
+       it.Advance()) {
+    SendRulesetToRenderProcess(&ruleset_data_, it.GetCurrentValue());
+  }
+}
+
+void ContentRulesetDistributor::Observe(
+    int type,
+    const content::NotificationSource& source,
+    const content::NotificationDetails& details) {
+  DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_CREATED);
+  if (!ruleset_data_.IsValid())
+    return;
+  SendRulesetToRenderProcess(
+      &ruleset_data_,
+      content::Source<content::RenderProcessHost>(source).ptr());
+}
+
+}  // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/content_ruleset_distributor.h b/components/subresource_filter/content/browser/content_ruleset_distributor.h
new file mode 100644
index 0000000..70afa362
--- /dev/null
+++ b/components/subresource_filter/content/browser/content_ruleset_distributor.h
@@ -0,0 +1,63 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_DISTRIBUTOR_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_DISTRIBUTOR_H_
+
+#include "base/files/file.h"
+#include "base/macros.h"
+#include "components/subresource_filter/core/browser/ruleset_distributor.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+namespace subresource_filter {
+
+// The content-layer specific implementation that receives the new versions of
+// subresource filtering rules from the RulesetService, and distributes them to
+// renderer processes, each with its own RulesetDealer.
+//
+// The distribution pipeline looks like this:
+//
+//                      RulesetService
+//                           |
+//                           v                  Browser
+//                    RulesetDistributor
+//                     |              |
+//        - - - - - - -|- - - - - - - |- - - - - - - - - -
+//                     |       |      |
+//                     v              v
+//           RulesetDealer     |   RulesetDealer
+//                 |                |       |
+//                 |           |    |       v
+//                 v                |      SubresourceFilterAgent
+//    SubresourceFilterAgent   |    v
+//                                SubresourceFilterAgent
+//                             |
+//
+//         Renderer #1         |          Renderer #n
+//
+class ContentRulesetDistributor : public RulesetDistributor,
+                                  content::NotificationObserver {
+ public:
+  ContentRulesetDistributor();
+  ~ContentRulesetDistributor() override;
+
+  // RulesetDistributor:
+  void PublishNewVersion(base::File ruleset_data) override;
+
+ private:
+  // content::NotificationObserver:
+  void Observe(int type,
+               const content::NotificationSource& source,
+               const content::NotificationDetails& details) override;
+
+  content::NotificationRegistrar notification_registrar_;
+  base::File ruleset_data_;
+
+  DISALLOW_COPY_AND_ASSIGN(ContentRulesetDistributor);
+};
+
+}  // namespace subresource_filter
+
+#endif  // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_CONTENT_RULESET_DISTRIBUTOR_H_
diff --git a/components/subresource_filter/content/browser/content_ruleset_distributor_unittest.cc b/components/subresource_filter/content/browser/content_ruleset_distributor_unittest.cc
new file mode 100644
index 0000000..c4db845
--- /dev/null
+++ b/components/subresource_filter/content/browser/content_ruleset_distributor_unittest.cc
@@ -0,0 +1,130 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/subresource_filter/content/browser/content_ruleset_distributor.h"
+
+#include <stddef.h>
+
+#include <string>
+#include <tuple>
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/run_loop.h"
+#include "components/subresource_filter/content/common/subresource_filter_messages.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "ipc/ipc_platform_file.h"
+#include "ipc/ipc_test_sink.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace subresource_filter {
+
+namespace {
+
+class NotifyingMockRenderProcessHost : public content::MockRenderProcessHost {
+ public:
+  explicit NotifyingMockRenderProcessHost(
+      content::BrowserContext* browser_context)
+      : content::MockRenderProcessHost(browser_context) {
+    content::NotificationService::current()->Notify(
+        content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+        content::Source<content::RenderProcessHost>(this),
+        content::NotificationService::NoDetails());
+  }
+};
+
+std::string ReadFileContents(base::File* file) {
+  size_t length = base::checked_cast<size_t>(file->GetLength());
+  std::string contents(length, 0);
+  file->Read(0, &contents[0], base::checked_cast<int>(length));
+  return contents;
+}
+
+// Extracts and takes ownership of the ruleset file handle in the IPC message.
+base::File ExtractRulesetFromMessage(const IPC::Message* message) {
+  std::tuple<IPC::PlatformFileForTransit> arg;
+  SubresourceFilterMsg_SetRulesetForProcess::Read(message, &arg);
+  return IPC::PlatformFileForTransitToFile(std::get<0>(arg));
+}
+
+}  // namespace
+
+class SubresourceFilterContentRulesetDistributorTest : public ::testing::Test {
+ public:
+  SubresourceFilterContentRulesetDistributorTest()
+      : existing_renderer_(&browser_context_) {}
+
+ protected:
+  void SetUp() override { ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); }
+
+  content::TestBrowserContext* browser_context() { return &browser_context_; }
+
+  base::FilePath scoped_temp_file() const {
+    return scoped_temp_dir_.path().AppendASCII("data");
+  }
+
+  void AssertSetRulesetForProcessMessageWithContent(
+      const IPC::Message* message,
+      const std::string& expected_contents) {
+    ASSERT_EQ(SubresourceFilterMsg_SetRulesetForProcess::ID, message->type());
+    base::File ruleset_file = ExtractRulesetFromMessage(message);
+    ASSERT_TRUE(ruleset_file.IsValid());
+    ASSERT_EQ(expected_contents, ReadFileContents(&ruleset_file));
+  }
+
+ private:
+  content::TestBrowserThreadBundle thread_bundle_;
+  content::TestBrowserContext browser_context_;
+  base::ScopedTempDir scoped_temp_dir_;
+  NotifyingMockRenderProcessHost existing_renderer_;
+
+  DISALLOW_COPY_AND_ASSIGN(SubresourceFilterContentRulesetDistributorTest);
+};
+
+TEST_F(SubresourceFilterContentRulesetDistributorTest,
+       NoRuleset_NoIPCMessages) {
+  NotifyingMockRenderProcessHost existing_renderer(browser_context());
+  ContentRulesetDistributor distributor;
+  NotifyingMockRenderProcessHost new_renderer(browser_context());
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(0u, existing_renderer.sink().message_count());
+  EXPECT_EQ(0u, new_renderer.sink().message_count());
+}
+
+TEST_F(SubresourceFilterContentRulesetDistributorTest,
+       PublishedRuleset_IsDistributedToExistingAndNewRenderers) {
+  const char kTestFileContents[] = "foobar";
+  base::WriteFile(scoped_temp_file(), kTestFileContents,
+                  strlen(kTestFileContents));
+
+  base::File file;
+  file.Initialize(scoped_temp_file(),
+                  base::File::FLAG_OPEN | base::File::FLAG_READ);
+
+  NotifyingMockRenderProcessHost existing_renderer(browser_context());
+  ContentRulesetDistributor distributor;
+  distributor.PublishNewVersion(std::move(file));
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_EQ(1u, existing_renderer.sink().message_count());
+  ASSERT_NO_FATAL_FAILURE(AssertSetRulesetForProcessMessageWithContent(
+      existing_renderer.sink().GetMessageAt(0), kTestFileContents));
+
+  NotifyingMockRenderProcessHost second_renderer(browser_context());
+  base::RunLoop().RunUntilIdle();
+
+  ASSERT_EQ(1u, second_renderer.sink().message_count());
+  ASSERT_NO_FATAL_FAILURE(AssertSetRulesetForProcessMessageWithContent(
+      second_renderer.sink().GetMessageAt(0), kTestFileContents));
+}
+
+}  // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver.cc
index 66274fc..24f91ed 100644
--- a/components/subresource_filter/content/browser/content_subresource_filter_driver.cc
+++ b/components/subresource_filter/content/browser/content_subresource_filter_driver.cc
@@ -19,9 +19,8 @@
     ActivationState activation_state) {
   // Must use legacy IPC to ensure the activation message arrives in-order, i.e.
   // before the load is committed on the renderer side.
-  render_frame_host_->Send(
-      new SubresourceFilterAgentMsg_ActivateForProvisionalLoad(
-          render_frame_host_->GetRoutingID(), activation_state));
+  render_frame_host_->Send(new SubresourceFilterMsg_ActivateForProvisionalLoad(
+      render_frame_host_->GetRoutingID(), activation_state));
 }
 
 }  // namespace subresource_filter
diff --git a/components/subresource_filter/content/common/OWNERS b/components/subresource_filter/content/common/OWNERS
index 6277118..42444bc 100644
--- a/components/subresource_filter/content/common/OWNERS
+++ b/components/subresource_filter/content/common/OWNERS
@@ -1,2 +1,2 @@
-per-file *messages*.h=set noparent
-per-file *messages*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
diff --git a/components/subresource_filter/content/common/subresource_filter_messages.h b/components/subresource_filter/content/common/subresource_filter_messages.h
index 7cbcf1a..f7f625a4 100644
--- a/components/subresource_filter/content/common/subresource_filter_messages.h
+++ b/components/subresource_filter/content/common/subresource_filter_messages.h
@@ -8,6 +8,7 @@
 #include "content/public/common/common_param_traits_macros.h"
 #include "ipc/ipc_message_macros.h"
 #include "ipc/ipc_message.h"
+#include "ipc/ipc_platform_file.h"
 
 #define IPC_MESSAGE_START SubresourceFilterMsgStart
 
@@ -18,9 +19,15 @@
 // Messages sent from the browser to the renderer.
 // ----------------------------------------------------------------------------
 
+// Sends a read-only mode file handle with the ruleset data to a renderer
+// process, containing the subresource filtering rules to be consulted for all
+// subsequent document loads that have subresource filtering activated.
+IPC_MESSAGE_CONTROL1(SubresourceFilterMsg_SetRulesetForProcess,
+                     IPC::PlatformFileForTransit /* ruleset_file */);
+
 // Instructs the renderer to activate subresource filtering for the currently
 // ongoing provisional document load in a frame. The message must arrive after
 // the provisional load starts, but before it is committed on the renderer side.
 // If no message arrives, the default behavior is ActivationState::DISABLED.
-IPC_MESSAGE_ROUTED1(SubresourceFilterAgentMsg_ActivateForProvisionalLoad,
-                    subresource_filter::ActivationState);
+IPC_MESSAGE_ROUTED1(SubresourceFilterMsg_ActivateForProvisionalLoad,
+                    subresource_filter::ActivationState /* activation_state */);
diff --git a/components/subresource_filter/content/renderer/BUILD.gn b/components/subresource_filter/content/renderer/BUILD.gn
index d9412cd..7af2f10 100644
--- a/components/subresource_filter/content/renderer/BUILD.gn
+++ b/components/subresource_filter/content/renderer/BUILD.gn
@@ -4,6 +4,8 @@
 
 source_set("renderer") {
   sources = [
+    "ruleset_dealer.cc",
+    "ruleset_dealer.h",
     "subresource_filter_agent.cc",
     "subresource_filter_agent.h",
   ]
@@ -13,5 +15,6 @@
     "//components/subresource_filter/core/common",
     "//content/public/common",
     "//content/public/renderer",
+    "//ipc",
   ]
 }
diff --git a/components/subresource_filter/content/renderer/ruleset_dealer.cc b/components/subresource_filter/content/renderer/ruleset_dealer.cc
new file mode 100644
index 0000000..df0bfc5
--- /dev/null
+++ b/components/subresource_filter/content/renderer/ruleset_dealer.cc
@@ -0,0 +1,37 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/subresource_filter/content/renderer/ruleset_dealer.h"
+
+#include <utility>
+
+#include "base/files/file.h"
+#include "base/logging.h"
+#include "components/subresource_filter/content/common/subresource_filter_messages.h"
+#include "components/subresource_filter/core/common/memory_mapped_ruleset.h"
+#include "ipc/ipc_message_macros.h"
+
+namespace subresource_filter {
+
+RulesetDealer::RulesetDealer() = default;
+RulesetDealer::~RulesetDealer() = default;
+
+bool RulesetDealer::OnControlMessageReceived(const IPC::Message& message) {
+  bool handled = true;
+  IPC_BEGIN_MESSAGE_MAP(RulesetDealer, message)
+    IPC_MESSAGE_HANDLER(SubresourceFilterMsg_SetRulesetForProcess,
+                        OnSetRulesetForProcess)
+    IPC_MESSAGE_UNHANDLED(handled = false)
+  IPC_END_MESSAGE_MAP()
+  return handled;
+}
+
+void RulesetDealer::OnSetRulesetForProcess(
+    const IPC::PlatformFileForTransit& platform_file) {
+  base::File file = IPC::PlatformFileForTransitToFile(platform_file);
+  DCHECK(file.IsValid());
+  ruleset_ = new MemoryMappedRuleset(std::move(file));
+}
+
+}  // namespace subresource_filter
diff --git a/components/subresource_filter/content/renderer/ruleset_dealer.h b/components/subresource_filter/content/renderer/ruleset_dealer.h
new file mode 100644
index 0000000..2054c61
--- /dev/null
+++ b/components/subresource_filter/content/renderer/ruleset_dealer.h
@@ -0,0 +1,45 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_RULESET_DEALER_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_RULESET_DEALER_H_
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "content/public/renderer/render_thread_observer.h"
+#include "ipc/ipc_platform_file.h"
+
+namespace IPC {
+class Message;
+}  // namespace IPC
+
+namespace subresource_filter {
+
+class MemoryMappedRuleset;
+
+// Memory maps the subresource filtering ruleset file received over IPC from the
+// RulesetDistributor, and makes it available to all SubresourceFilterAgents
+// within the current render process.
+//
+// See the distribution pipeline diagram in content_ruleset_distributor.h.
+class RulesetDealer : public content::RenderThreadObserver {
+ public:
+  RulesetDealer();
+  ~RulesetDealer() override;
+
+  const scoped_refptr<MemoryMappedRuleset>& ruleset() { return ruleset_; }
+
+ private:
+  // content::RenderThreadObserver:
+  bool OnControlMessageReceived(const IPC::Message& message) override;
+  void OnSetRulesetForProcess(const IPC::PlatformFileForTransit& file);
+
+  scoped_refptr<MemoryMappedRuleset> ruleset_;
+
+  DISALLOW_COPY_AND_ASSIGN(RulesetDealer);
+};
+
+}  // namespace subresource_filter
+
+#endif  // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_RENDERER_RULESET_DEALER_H_
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.cc b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
index 9aa8860..4330a5e6 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent.cc
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
@@ -4,7 +4,14 @@
 
 #include "components/subresource_filter/content/renderer/subresource_filter_agent.h"
 
+#include <climits>
+
+#include "base/memory/ref_counted.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
 #include "components/subresource_filter/content/common/subresource_filter_messages.h"
+#include "components/subresource_filter/content/renderer/ruleset_dealer.h"
+#include "components/subresource_filter/core/common/memory_mapped_ruleset.h"
 #include "content/public/renderer/render_frame.h"
 #include "ipc/ipc_message.h"
 #include "third_party/WebKit/public/platform/WebDocumentSubresourceFilter.h"
@@ -17,27 +24,41 @@
 
 namespace {
 
-// Placeholder subresource filter implementation that disallows all loads.
+// Placeholder subresource filter implementation that treats the entire ruleset
+// as the UTF-8 representation of a string, and will disallow subresource loads
+// from URL paths having this string as a suffix.
 // TODO(engedy): Replace this with the actual filtering logic.
-class NaysayerFilter : public blink::WebDocumentSubresourceFilter {
+class PathSuffixFilter : public blink::WebDocumentSubresourceFilter {
  public:
-  NaysayerFilter() {}
-  ~NaysayerFilter() override {}
+  explicit PathSuffixFilter(const scoped_refptr<MemoryMappedRuleset>& ruleset)
+      : ruleset_(ruleset) {
+    static_assert(CHAR_BIT == 8, "Assumed char was 8 bits.");
+    disallowed_suffix_ = base::StringPiece(
+        reinterpret_cast<const char*>(ruleset_->data()), ruleset_->length());
+  }
+  ~PathSuffixFilter() override {}
 
   bool allowLoad(const blink::WebURL& resourceUrl,
                  blink::WebURLRequest::RequestContext) override {
-    return false;
+    return disallowed_suffix_.empty() ||
+           !base::EndsWith(GURL(resourceUrl).path(), disallowed_suffix_,
+                           base::CompareCase::SENSITIVE);
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(NaysayerFilter);
+  scoped_refptr<MemoryMappedRuleset> ruleset_;
+  base::StringPiece disallowed_suffix_;
+
+  DISALLOW_COPY_AND_ASSIGN(PathSuffixFilter);
 };
 
 }  // namespace
 
 SubresourceFilterAgent::SubresourceFilterAgent(
-    content::RenderFrame* render_frame)
+    content::RenderFrame* render_frame,
+    RulesetDealer* ruleset_dealer)
     : content::RenderFrameObserver(render_frame),
+      ruleset_dealer_(ruleset_dealer),
       activation_state_for_provisional_load_(ActivationState::DISABLED) {}
 
 SubresourceFilterAgent::~SubresourceFilterAgent() = default;
@@ -53,16 +74,18 @@
 void SubresourceFilterAgent::DidCommitProvisionalLoad(
     bool is_new_navigation,
     bool is_same_page_navigation) {
-  if (activation_state_for_provisional_load_ == ActivationState::ENABLED) {
+  if (activation_state_for_provisional_load_ == ActivationState::ENABLED &&
+      ruleset_dealer_->ruleset()) {
     blink::WebLocalFrame* web_frame = render_frame()->GetWebFrame();
-    web_frame->dataSource()->setSubresourceFilter(new NaysayerFilter);
+    web_frame->dataSource()->setSubresourceFilter(
+        new PathSuffixFilter(ruleset_dealer_->ruleset()));
   }
 }
 
 bool SubresourceFilterAgent::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(SubresourceFilterAgent, message)
-    IPC_MESSAGE_HANDLER(SubresourceFilterAgentMsg_ActivateForProvisionalLoad,
+    IPC_MESSAGE_HANDLER(SubresourceFilterMsg_ActivateForProvisionalLoad,
                         OnActivateForProvisionalLoad)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.h b/components/subresource_filter/content/renderer/subresource_filter_agent.h
index e887623..a93c77a 100644
--- a/components/subresource_filter/content/renderer/subresource_filter_agent.h
+++ b/components/subresource_filter/content/renderer/subresource_filter_agent.h
@@ -11,13 +11,16 @@
 
 namespace subresource_filter {
 
+class RulesetDealer;
+
 // The renderer-side agent of the ContentSubresourceFilterDriver. There is one
 // instance per RenderFrame, responsible for setting up the subresource filter
 // for the ongoing provisional document load in the frame when instructed to do
 // so by the driver.
 class SubresourceFilterAgent : public content::RenderFrameObserver {
  public:
-  explicit SubresourceFilterAgent(content::RenderFrame* render_frame);
+  explicit SubresourceFilterAgent(content::RenderFrame* render_frame,
+                                  RulesetDealer* ruleset_dealer);
   ~SubresourceFilterAgent() override;
 
  private:
@@ -32,6 +35,9 @@
 
   void OnActivateForProvisionalLoad(ActivationState activation_state);
 
+  // Owned by the ChromeContentRendererClient and outlives us.
+  RulesetDealer* ruleset_dealer_;
+
   ActivationState activation_state_for_provisional_load_;
 
   DISALLOW_COPY_AND_ASSIGN(SubresourceFilterAgent);
diff --git a/components/subresource_filter/core/common/BUILD.gn b/components/subresource_filter/core/common/BUILD.gn
index 5d4a76b..3352ab6 100644
--- a/components/subresource_filter/core/common/BUILD.gn
+++ b/components/subresource_filter/core/common/BUILD.gn
@@ -6,6 +6,8 @@
   sources = [
     "activation_state.cc",
     "activation_state.h",
+    "memory_mapped_ruleset.cc",
+    "memory_mapped_ruleset.h",
   ]
   deps = [
     "//base",
diff --git a/components/subresource_filter/core/common/memory_mapped_ruleset.cc b/components/subresource_filter/core/common/memory_mapped_ruleset.cc
new file mode 100644
index 0000000..8e479f1
--- /dev/null
+++ b/components/subresource_filter/core/common/memory_mapped_ruleset.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/subresource_filter/core/common/memory_mapped_ruleset.h"
+
+#include <utility>
+
+namespace subresource_filter {
+
+MemoryMappedRuleset::MemoryMappedRuleset(base::File ruleset_file) {
+  ruleset_.Initialize(std::move(ruleset_file));
+}
+
+MemoryMappedRuleset::~MemoryMappedRuleset() {}
+
+}  // namespace subresource_filter
diff --git a/components/subresource_filter/core/common/memory_mapped_ruleset.h b/components/subresource_filter/core/common/memory_mapped_ruleset.h
new file mode 100644
index 0000000..c6dacaf
--- /dev/null
+++ b/components/subresource_filter/core/common/memory_mapped_ruleset.h
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_MEMORY_MAPPED_RULESET_H_
+#define COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_MEMORY_MAPPED_RULESET_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/files/file.h"
+#include "base/files/memory_mapped_file.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/numerics/safe_conversions.h"
+
+namespace subresource_filter {
+
+// A reference-counted wrapper around base::MemoryMappedFile. The |ruleset_file|
+// supplied in the constructor is kept memory-mapped and is safe to access until
+// the last reference to this instance is dropped.
+class MemoryMappedRuleset : public base::RefCounted<MemoryMappedRuleset> {
+ public:
+  explicit MemoryMappedRuleset(base::File ruleset_file);
+
+  const uint8_t* data() const { return ruleset_.data(); }
+  size_t length() const { return base::strict_cast<size_t>(ruleset_.length()); }
+
+ private:
+  friend class base::RefCounted<MemoryMappedRuleset>;
+  ~MemoryMappedRuleset();
+
+  base::MemoryMappedFile ruleset_;
+
+  DISALLOW_COPY_AND_ASSIGN(MemoryMappedRuleset);
+};
+
+}  // namespace subresource_filter
+
+#endif  // COMPONENTS_SUBRESOURCE_FILTER_CORE_COMMON_MEMORY_MAPPED_RULESET_H_
diff --git a/components/test/data/cast_certificate/certificates/intermediate_serialnumber_toolong.pem b/components/test/data/cast_certificate/certificates/intermediate_serialnumber_toolong.pem
new file mode 100644
index 0000000..3392a2d1
--- /dev/null
+++ b/components/test/data/cast_certificate/certificates/intermediate_serialnumber_toolong.pem
@@ -0,0 +1,270 @@
+The first intermediate in this chain (CN=Sony so16vic CA) has a serial number
+that is 21 octets. This is not valid according to RFC 5280, which limits their
+length to 20 octets.
+
+$ openssl x509 -text -noout < [CERTIFICATE]
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+             (Negative)08:54:7d:b3:4f:1f:68:ab:63:ae:3a:ca:cb:ef:13:99:1c:d3:63:d6
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=JP, ST=Tokyo, L=Minato-ku, O=Sony Corporation, OU=New Audio, CN=Sony so16vic CA
+        Validity
+            Not Before: Feb 22 08:17:08 2016 GMT
+            Not After : Feb 17 08:17:08 2036 GMT
+        Subject: CN=8C579B806FFC8A9DFFFF F8:8F:CA:6B:E6:DA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:d1:ad:a2:58:33:a0:7f:55:94:b9:17:78:de:77:
+                    c8:28:ed:f3:33:b5:60:e6:2d:b7:86:97:41:ce:a2:
+                    60:19:14:80:53:2a:54:7f:4a:17:8b:51:75:f4:f1:
+                    41:d1:04:ed:86:1d:66:81:e3:2a:03:70:bb:9b:db:
+                    b5:2c:7b:d7:dd:68:d4:dc:d9:c9:f7:6f:2b:08:d3:
+                    18:b7:04:3c:00:d5:cf:f9:b1:6a:84:73:cd:dc:a2:
+                    3e:f5:a0:b6:3d:26:a6:4c:21:8d:1d:00:71:cb:0d:
+                    f9:2d:7c:bb:7a:b4:20:b4:85:a5:73:3a:eb:c2:d8:
+                    16:ec:94:1d:1e:30:4a:38:77:78:33:12:ac:06:b6:
+                    45:49:ad:f8:cd:a8:e5:61:d7:6e:92:af:dc:cb:61:
+                    c1:88:ab:00:75:b1:df:23:42:dc:47:08:2f:96:9d:
+                    2b:74:5d:6f:a9:3a:f4:c0:1b:07:fe:5f:06:51:fc:
+                    0f:8e:b0:71:fe:60:5e:79:78:b2:a9:1c:6e:85:04:
+                    e4:93:24:f4:4e:a8:cf:f7:06:95:e4:14:81:f6:19:
+                    0e:ce:fe:22:c3:ae:3b:6b:8b:fe:90:61:2b:56:37:
+                    8a:93:43:73:cb:22:a7:f1:ff:e0:75:0f:df:ff:72:
+                    af:3f:7e:2e:5d:15:06:8e:20:1a:b6:1a:6e:93:f2:
+                    eb:69
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            X509v3 Subject Key Identifier: 
+                CF:E8:B7:7B:89:A2:AF:64:AA:17:83:76:0C:51:D5:22:A5:6A:DA:6C
+            X509v3 Authority Key Identifier: 
+                keyid:FA:1F:9C:C9:DB:9D:A6:2F:33:A7:F9:C9:8A:6A:72:63:56:3F:EF:D1
+
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Extended Key Usage: 
+                TLS Web Client Authentication
+            X509v3 Certificate Policies: 
+                Policy: 1.3.6.1.4.1.11129.2.5.2
+
+    Signature Algorithm: sha256WithRSAEncryption
+         00:89:21:a9:ed:50:b5:a4:1f:08:dc:ce:b7:ca:cf:e5:14:61:
+         3c:5d:d3:13:c5:9c:1a:93:b5:b0:2a:78:23:23:5f:da:43:b5:
+         71:25:d6:88:d7:55:97:5b:10:88:b7:80:98:a0:79:4a:3a:72:
+         39:e4:57:64:3c:e4:e9:67:98:83:2e:58:43:35:af:74:7c:e5:
+         ce:2d:69:85:9a:e6:0f:74:57:2f:c9:79:66:29:29:1a:05:52:
+         f8:60:b9:04:31:6f:c9:75:df:98:70:15:a8:c4:c0:8d:af:73:
+         f7:d2:61:b9:65:0a:01:e8:3a:b8:84:af:c3:90:d2:fd:8d:a4:
+         33:4e:50:52:7c:c1:35:8b:92:0a:bf:5c:41:5c:0f:62:cd:b0:
+         4d:a7:d7:be:23:1b:33:1e:5b:fc:54:0b:b3:c1:93:30:34:f3:
+         5f:fb:15:4c:6d:ee:72:3d:2a:c0:73:59:1f:18:99:bc:d3:b9:
+         65:08:cf:03:63:b5:88:be:a6:1b:f7:6a:b7:90:83:ab:20:73:
+         bb:bd:c6:86:88:1a:a6:24:9e:1a:5a:7f:c4:e4:23:da:2b:14:
+         a8:db:85:5b:3d:92:f3:5d:9a:14:19:c7:0e:19:3a:65:41:44:
+         ee:5e:3e:7b:46:49:52:07:af:ee:ff:41:98:2e:e3:e3:ab:37:
+         a6:35:8a:85
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIU96uCTLDgl1ScUcU1NBDsZuMsnCowDQYJKoZIhvcNAQEL
+BQAwejELMAkGA1UEBhMCSlAxDjAMBgNVBAgTBVRva3lvMRIwEAYDVQQHEwlNaW5h
+dG8ta3UxGTAXBgNVBAoTEFNvbnkgQ29ycG9yYXRpb24xEjAQBgNVBAsTCU5ldyBB
+dWRpbzEYMBYGA1UEAxMPU29ueSBzbzE2dmljIENBMB4XDTE2MDIyMjA4MTcwOFoX
+DTM2MDIxNzA4MTcwOFowMTEvMC0GA1UEAwwmOEM1NzlCODA2RkZDOEE5REZGRkYg
+Rjg6OEY6Q0E6NkI6RTY6REEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDRraJYM6B/VZS5F3jed8go7fMztWDmLbeGl0HOomAZFIBTKlR/SheLUXX08UHR
+BO2GHWaB4yoDcLub27Use9fdaNTc2cn3bysI0xi3BDwA1c/5sWqEc83coj71oLY9
+JqZMIY0dAHHLDfktfLt6tCC0haVzOuvC2BbslB0eMEo4d3gzEqwGtkVJrfjNqOVh
+126Sr9zLYcGIqwB1sd8jQtxHCC+WnSt0XW+pOvTAGwf+XwZR/A+OsHH+YF55eLKp
+HG6FBOSTJPROqM/3BpXkFIH2GQ7O/iLDrjtri/6QYStWN4qTQ3PLIqfx/+B1D9//
+cq8/fi5dFQaOIBq2Gm6T8utpAgMBAAGjgYkwgYYwCQYDVR0TBAIwADAdBgNVHQ4E
+FgQUz+i3e4mir2SqF4N2DFHVIqVq2mwwHwYDVR0jBBgwFoAU+h+cydudpi8zp/nJ
+impyY1Y/79EwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMBcGA1Ud
+IAQQMA4wDAYKKwYBBAHWeQIFAjANBgkqhkiG9w0BAQsFAAOCAQEAAIkhqe1QtaQf
+CNzOt8rP5RRhPF3TE8WcGpO1sCp4IyNf2kO1cSXWiNdVl1sQiLeAmKB5SjpyOeRX
+ZDzk6WeYgy5YQzWvdHzlzi1phZrmD3RXL8l5ZikpGgVS+GC5BDFvyXXfmHAVqMTA
+ja9z99JhuWUKAeg6uISvw5DS/Y2kM05QUnzBNYuSCr9cQVwPYs2wTafXviMbMx5b
+/FQLs8GTMDTzX/sVTG3ucj0qwHNZHxiZvNO5ZQjPA2O1iL6mG/dqt5CDqyBzu73G
+hogapiSeGlp/xOQj2isUqNuFWz2S812aFBnHDhk6ZUFE7l4+e0ZJUgev7v9BmC7j
+46s3pjWKhQ==
+-----END CERTIFICATE-----
+
+$ openssl x509 -text -noout < [CERTIFICATE]
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            de:84:71:ee:a7:0c:9d:4c:95:70:43:5b:ee:55:6c:da:cb:e9:4d:dd
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=JP, ST=Tokyo, L=Minato-ku, O=Sony Corporation, OU=New Audio, CN=Cast Audio Sony CA
+        Validity
+            Not Before: Feb 22 08:17:08 2016 GMT
+            Not After : Feb 17 08:17:08 2036 GMT
+        Subject: C=JP, ST=Tokyo, L=Minato-ku, O=Sony Corporation, OU=New Audio, CN=Sony so16vic CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:be:4e:16:38:4d:f4:82:93:e5:e6:55:f8:33:fd:
+                    41:18:7b:5d:9f:2c:cf:b0:8b:b4:cf:b8:a5:d1:e6:
+                    b9:65:aa:d4:d8:84:b6:0a:dd:64:be:45:5a:65:f2:
+                    cd:d0:3e:cc:bd:16:e9:8a:dc:0e:15:44:85:6a:37:
+                    af:f6:00:ca:7f:92:ff:64:39:07:3c:44:fd:d7:63:
+                    c7:e6:09:8c:47:26:2b:01:e0:b0:16:fb:46:13:89:
+                    4c:0e:2e:72:dd:d7:85:81:0d:e5:79:6f:33:ec:c4:
+                    a6:7b:f3:41:ff:58:eb:73:69:41:ec:a3:a7:e1:fe:
+                    99:44:6b:51:b3:4c:9a:1f:9f:9f:82:f4:aa:85:0d:
+                    bd:f3:a5:53:3a:66:63:f1:d8:65:b8:bf:6e:d9:1e:
+                    d7:3a:a3:a8:73:c5:55:f1:2f:58:9c:7d:b6:c0:16:
+                    d2:bf:02:07:4d:e1:15:f9:d4:3b:95:6a:98:c2:25:
+                    3f:4e:36:af:ea:eb:4b:cb:d6:6c:ff:22:8a:d5:0d:
+                    3d:1a:e4:4d:70:fa:94:35:83:8e:a9:ad:fa:f2:8d:
+                    e3:84:b4:05:29:bc:75:7b:83:f3:52:97:99:83:f1:
+                    76:2f:b9:f5:80:24:15:4b:02:3f:12:d7:97:fd:13:
+                    ee:00:9f:95:a3:f7:b1:13:7e:37:8a:17:1f:fb:8c:
+                    ba:87
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:TRUE, pathlen:0
+            X509v3 Subject Key Identifier: 
+                FA:1F:9C:C9:DB:9D:A6:2F:33:A7:F9:C9:8A:6A:72:63:56:3F:EF:D1
+            X509v3 Authority Key Identifier: 
+                keyid:F5:CD:99:72:18:36:F2:F6:B5:DB:A7:FE:04:8E:CC:D0:D6:F9:6F:89
+
+            X509v3 Key Usage: 
+                Certificate Sign, CRL Sign
+            X509v3 Certificate Policies: 
+                Policy: 1.3.6.1.4.1.11129.2.5.2
+
+    Signature Algorithm: sha256WithRSAEncryption
+         82:01:e1:78:39:ec:b0:10:a3:f4:b9:05:07:b8:58:04:5c:52:
+         69:18:47:2c:24:52:bf:9f:37:17:a4:03:1e:d8:79:9c:04:6b:
+         9f:b3:96:a7:80:c5:e8:f9:ba:03:ac:98:29:5c:3c:27:b3:13:
+         8f:f1:f5:1c:1f:10:ad:96:ef:80:08:2c:ee:bd:67:71:99:a9:
+         bb:bb:d5:e8:93:da:06:23:1b:db:dd:91:5d:ac:43:17:60:9e:
+         52:1e:d5:e4:bf:8e:61:56:d0:b1:b0:c3:e6:cc:af:43:78:77:
+         26:db:4c:db:36:34:ae:6a:75:c8:8c:8c:85:64:31:89:c4:53:
+         f5:49:d2:86:11:54:4b:01:c5:6a:56:a2:95:16:76:c9:e6:2b:
+         3a:cf:82:b3:4e:20:64:57:74:d6:68:4b:4b:0b:cb:4a:62:ee:
+         0d:a5:80:23:6d:25:c3:d3:39:d6:01:2b:d7:86:3e:47:02:e2:
+         e5:b3:7a:43:86:8a:7d:7b:88:de:5d:48:b1:4e:65:56:b0:a6:
+         85:f6:42:62:49:82:fc:da:50:17:a1:f9:3a:b7:b9:76:8d:1d:
+         b5:76:8f:14:e5:4a:4d:bc:c5:fd:ab:dd:e4:51:2e:d9:cb:b1:
+         82:6b:c4:d9:ab:7b:88:2d:4f:a8:8e:99:e9:d1:07:f9:cc:b6:
+         db:dd:f0:be
+-----BEGIN CERTIFICATE-----
+MIID/zCCAuegAwIBAgIVAN6Ece6nDJ1MlXBDW+5VbNrL6U3dMA0GCSqGSIb3DQEB
+CwUAMH0xCzAJBgNVBAYTAkpQMQ4wDAYDVQQIEwVUb2t5bzESMBAGA1UEBxMJTWlu
+YXRvLWt1MRkwFwYDVQQKExBTb255IENvcnBvcmF0aW9uMRIwEAYDVQQLEwlOZXcg
+QXVkaW8xGzAZBgNVBAMTEkNhc3QgQXVkaW8gU29ueSBDQTAeFw0xNjAyMjIwODE3
+MDhaFw0zNjAyMTcwODE3MDhaMHoxCzAJBgNVBAYTAkpQMQ4wDAYDVQQIEwVUb2t5
+bzESMBAGA1UEBxMJTWluYXRvLWt1MRkwFwYDVQQKExBTb255IENvcnBvcmF0aW9u
+MRIwEAYDVQQLEwlOZXcgQXVkaW8xGDAWBgNVBAMTD1Nvbnkgc28xNnZpYyBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL5OFjhN9IKT5eZV+DP9QRh7
+XZ8sz7CLtM+4pdHmuWWq1NiEtgrdZL5FWmXyzdA+zL0W6YrcDhVEhWo3r/YAyn+S
+/2Q5BzxE/ddjx+YJjEcmKwHgsBb7RhOJTA4uct3XhYEN5XlvM+zEpnvzQf9Y63Np
+Qeyjp+H+mURrUbNMmh+fn4L0qoUNvfOlUzpmY/HYZbi/btke1zqjqHPFVfEvWJx9
+tsAW0r8CB03hFfnUO5VqmMIlP042r+rrS8vWbP8iitUNPRrkTXD6lDWDjqmt+vKN
+44S0BSm8dXuD81KXmYPxdi+59YAkFUsCPxLXl/0T7gCflaP3sRN+N4oXH/uMuocC
+AwEAAaN5MHcwDwYDVR0TBAgwBgEB/wIBADAdBgNVHQ4EFgQU+h+cydudpi8zp/nJ
+impyY1Y/79EwHwYDVR0jBBgwFoAU9c2Zchg28va126f+BI7M0Nb5b4kwCwYDVR0P
+BAQDAgEGMBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFAjANBgkqhkiG9w0BAQsFAAOC
+AQEAggHheDnssBCj9LkFB7hYBFxSaRhHLCRSv583F6QDHth5nARrn7OWp4DF6Pm6
+A6yYKVw8J7MTj/H1HB8QrZbvgAgs7r1ncZmpu7vV6JPaBiMb292RXaxDF2CeUh7V
+5L+OYVbQsbDD5syvQ3h3JttM2zY0rmp1yIyMhWQxicRT9UnShhFUSwHFalailRZ2
+yeYrOs+Cs04gZFd01mhLSwvLSmLuDaWAI20lw9M51gEr14Y+RwLi5bN6Q4aKfXuI
+3l1IsU5lVrCmhfZCYkmC/NpQF6H5Ore5do0dtXaPFOVKTbzF/avd5FEu2cuxgmvE
+2at7iC1PqI6Z6dEH+cy2293wvg==
+-----END CERTIFICATE-----
+
+$ openssl x509 -text -noout < [CERTIFICATE]
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 32 (0x20)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=California, L=Mountain View, O=Google Inc, OU=Cast, CN=Cast Root CA
+        Validity
+            Not Before: Feb  6 20:36:16 2015 GMT
+            Not After : Feb  1 20:36:16 2035 GMT
+        Subject: C=JP, ST=Tokyo, L=Minato-ku, O=Sony Corporation, OU=New Audio, CN=Cast Audio Sony CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ca:4f:a1:7c:f3:31:a7:02:92:02:f7:cc:4e:1f:
+                    26:2f:87:10:a9:64:62:0f:82:77:b4:1b:55:b1:4a:
+                    85:bd:f8:1e:08:75:99:ed:ac:56:0f:1a:55:02:d0:
+                    f9:f1:41:7c:7c:03:74:dd:c7:ad:56:ff:9a:7a:f8:
+                    4a:86:b5:50:2d:b2:26:7f:bd:32:ea:66:de:17:3b:
+                    38:aa:fd:05:ca:b2:84:c4:02:59:b3:b4:e9:18:ec:
+                    aa:04:f1:0a:d0:70:b9:50:d8:6c:a6:bd:3b:36:ca:
+                    d7:22:ec:13:54:c6:22:6f:6c:63:a4:1b:1c:76:ed:
+                    0b:03:84:67:ff:ca:44:5a:e4:55:33:05:d9:7f:05:
+                    07:d0:52:03:57:40:30:96:b7:94:bc:85:8a:78:84:
+                    6e:f8:ea:2b:2e:a6:d9:96:c4:6a:72:be:15:49:e9:
+                    4a:b6:59:76:bb:d4:79:79:6f:c0:19:99:19:e0:52:
+                    21:fb:cb:cd:8e:41:be:77:b1:12:a3:7f:c9:85:4d:
+                    fb:2f:50:e9:84:73:77:f8:75:98:34:b7:fe:3c:44:
+                    c8:d9:96:66:75:e7:63:98:2e:ca:a1:10:8a:bc:63:
+                    4d:69:4d:52:2a:6f:0e:7f:fa:05:9a:22:72:e5:6b:
+                    91:72:b0:21:3b:61:e9:80:68:c3:63:c0:83:bf:51:
+                    49:e9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:TRUE, pathlen:1
+            X509v3 Subject Key Identifier: 
+                F5:CD:99:72:18:36:F2:F6:B5:DB:A7:FE:04:8E:CC:D0:D6:F9:6F:89
+            X509v3 Authority Key Identifier: 
+                keyid:7C:9A:1E:7D:DF:79:54:BC:D7:CC:5E:CA:99:86:45:79:65:74:28:19
+
+            X509v3 Key Usage: 
+                Certificate Sign, CRL Sign
+            X509v3 Certificate Policies: 
+                Policy: 1.3.6.1.4.1.11129.2.5.2
+
+    Signature Algorithm: sha256WithRSAEncryption
+         a8:99:1a:0f:31:60:6e:7b:41:94:de:09:01:eb:8b:b7:1f:72:
+         54:14:96:9b:80:37:c9:62:02:b9:d9:db:26:33:53:c5:c1:ed:
+         83:b4:4f:21:9d:58:e4:13:9d:cb:06:54:c7:6f:a6:e8:99:30:
+         5a:cd:b0:cb:6d:81:25:d2:99:08:24:25:0e:83:a9:06:46:ec:
+         56:ac:4d:ef:02:e6:c5:6f:99:3c:c5:01:8f:a7:f0:b0:af:3b:
+         12:23:3a:e1:6b:e1:14:84:e3:4d:b0:e5:eb:04:8d:da:ad:01:
+         13:b6:a8:37:a1:1d:99:76:78:a5:54:c8:d0:ed:16:9c:7e:e7:
+         cf:eb:36:f1:96:1e:da:2a:73:9d:18:32:5a:e7:dc:03:2b:7e:
+         84:fb:a5:1f:bb:13:67:34:87:49:03:2e:02:1d:0a:14:dd:58:
+         b7:1d:71:34:f9:69:8a:06:9f:c5:1c:db:bf:29:aa:e4:80:11:
+         a6:f6:e4:22:fd:61:5a:95:66:46:a2:8b:b1:8f:63:8d:64:76:
+         d0:99:d2:43:c8:b7:df:e4:bf:08:84:7f:4b:b0:8c:e2:04:1c:
+         80:08:52:7a:56:91:15:26:8d:13:5f:f0:d3:5c:ff:1e:f9:a4:
+         21:11:e4:45:b3:c4:1e:63:94:68:94:c9:28:de:99:4e:61:24:
+         9e:d8:f1:8b
+
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIBIDANBgkqhkiG9w0BAQsFADB1MQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEG
+A1UECgwKR29vZ2xlIEluYzENMAsGA1UECwwEQ2FzdDEVMBMGA1UEAwwMQ2FzdCBS
+b290IENBMB4XDTE1MDIwNjIwMzYxNloXDTM1MDIwMTIwMzYxNlowfTELMAkGA1UE
+BhMCSlAxDjAMBgNVBAgTBVRva3lvMRIwEAYDVQQHEwlNaW5hdG8ta3UxGTAXBgNV
+BAoTEFNvbnkgQ29ycG9yYXRpb24xEjAQBgNVBAsTCU5ldyBBdWRpbzEbMBkGA1UE
+AxMSQ2FzdCBBdWRpbyBTb255IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAyk+hfPMxpwKSAvfMTh8mL4cQqWRiD4J3tBtVsUqFvfgeCHWZ7axWDxpV
+AtD58UF8fAN03cetVv+aevhKhrVQLbImf70y6mbeFzs4qv0FyrKExAJZs7TpGOyq
+BPEK0HC5UNhspr07NsrXIuwTVMYib2xjpBscdu0LA4Rn/8pEWuRVMwXZfwUH0FID
+V0AwlreUvIWKeIRu+OorLqbZlsRqcr4VSelKtll2u9R5eW/AGZkZ4FIh+8vNjkG+
+d7ESo3/JhU37L1DphHN3+HWYNLf+PETI2ZZmdedjmC7KoRCKvGNNaU1SKm8Of/oF
+miJy5WuRcrAhO2HpgGjDY8CDv1FJ6QIDAQABo3kwdzAPBgNVHRMECDAGAQH/AgEB
+MB0GA1UdDgQWBBT1zZlyGDby9rXbp/4EjszQ1vlviTAfBgNVHSMEGDAWgBR8mh59
+33lUvNfMXsqZhkV5ZXQoGTALBgNVHQ8EBAMCAQYwFwYDVR0gBBAwDjAMBgorBgEE
+AdZ5AgUCMA0GCSqGSIb3DQEBCwUAA4IBAQComRoPMWBue0GU3gkB64u3H3JUFJab
+gDfJYgK52dsmM1PFwe2DtE8hnVjkE53LBlTHb6bomTBazbDLbYEl0pkIJCUOg6kG
+RuxWrE3vAubFb5k8xQGPp/CwrzsSIzrha+EUhONNsOXrBI3arQETtqg3oR2Zdnil
+VMjQ7RacfufP6zbxlh7aKnOdGDJa59wDK36E+6UfuxNnNIdJAy4CHQoU3Vi3HXE0
++WmKBp/FHNu/KarkgBGm9uQi/WFalWZGoouxj2ONZHbQmdJDyLff5L8IhH9LsIzi
+BByACFJ6VpEVJo0TX/DTXP8e+aQhEeRFs8QeY5RolMko3plOYSSe2PGL
+-----END CERTIFICATE-----
diff --git a/components/test_runner/event_sender.cc b/components/test_runner/event_sender.cc
index 4c608b63..e2db37e 100644
--- a/components/test_runner/event_sender.cc
+++ b/components/test_runner/event_sender.cc
@@ -1565,6 +1565,10 @@
     code = ui::VKEY_ESCAPE;
     domKeyString.assign("Escape");
     domCodeString.assign("Escape");
+  } else if ("Tab" == code_str) {
+    code = ui::VKEY_TAB;
+    domKeyString.assign("Tab");
+    domCodeString.assign("Tab");
   } else {
     // Compare the input string with the function-key names defined by the
     // DOM spec (i.e. "F1",...,"F24"). If the input string is a function-key
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc
index 3ba4a5b..49b9434 100644
--- a/content/app/content_main_runner.cc
+++ b/content/app/content_main_runner.cc
@@ -178,10 +178,8 @@
 
 #if defined(V8_USE_EXTERNAL_STARTUP_DATA) && defined(OS_ANDROID)
 #if defined __LP64__
-#define kV8NativesDataDescriptor kV8NativesDataDescriptor64
 #define kV8SnapshotDataDescriptor kV8SnapshotDataDescriptor64
 #else
-#define kV8NativesDataDescriptor kV8NativesDataDescriptor32
 #define kV8SnapshotDataDescriptor kV8SnapshotDataDescriptor32
 #endif
 #endif
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index d9180ab8..fe4a920 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -66,6 +66,7 @@
     "//gpu/command_buffer/client:gles2_interface",
     "//ipc/mojo",
     "//media",
+    "//media/capture",
     "//media/gpu/ipc/client",
     "//media/midi",
     "//media/mojo/interfaces:image_capture",
@@ -349,6 +350,7 @@
     deps += [
       "//content/public/android:jni",
       "//media",
+      "//media/capture/video/android",
       "//media/mojo/interfaces",
       "//mojo/android:libsystem_java",
       "//ui/android",
diff --git a/content/browser/bad_message.cc b/content/browser/bad_message.cc
index f7e30368..9e2910f 100644
--- a/content/browser/bad_message.cc
+++ b/content/browser/bad_message.cc
@@ -4,8 +4,10 @@
 
 #include "content/browser/bad_message.h"
 
+#include "base/debug/crash_logging.h"
 #include "base/logging.h"
 #include "base/metrics/sparse_histogram.h"
+#include "base/strings/string_number_conversions.h"
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/browser/render_process_host.h"
 
@@ -17,6 +19,8 @@
 void LogBadMessage(BadMessageReason reason) {
   LOG(ERROR) << "Terminating renderer for bad IPC message, reason " << reason;
   UMA_HISTOGRAM_SPARSE_SLOWLY("Stability.BadMessageTerminated.Content", reason);
+  base::debug::SetCrashKeyValue("bad_message_reason",
+                                base::IntToString(reason));
 }
 
 }  // namespace
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h
index 21f56c8..d9b01534 100644
--- a/content/browser/bad_message.h
+++ b/content/browser/bad_message.h
@@ -145,6 +145,9 @@
   RFH_FAIL_PROVISIONAL_LOAD_NO_ERROR = 121,
   NI_IN_PAGE_NAVIGATION = 122,
   RPH_MOJO_PROCESS_ERROR = 123,
+  DBMF_INVALID_ORIGIN_ON_GET_SPACE = 124,
+  DBMF_INVALID_ORIGIN_ON_MODIFIED = 125,
+  DBMF_INVALID_ORIGIN_ON_CLOSED = 126,
 
   // Please add new elements here. The naming convention is abbreviated class
   // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc
index 43fd58e..408dc5c4 100644
--- a/content/browser/cache_storage/cache_storage_cache.cc
+++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -274,7 +274,6 @@
   std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
   CacheStorageCache::ErrorCallback callback;
   disk_cache::ScopedEntryPtr cache_entry;
-  int64_t available_bytes = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PutContext);
@@ -358,23 +357,70 @@
                                       scoped_refptr<net::IOBuffer> buffer,
                                       int buf_len) {
   if (!LazyInitialize()) {
-    callback.Run(CACHE_STORAGE_ERROR_STORAGE);
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_STORAGE));
     return;
   }
-  ErrorCallback pending_callback =
-      base::Bind(&CacheStorageCache::PendingErrorCallback,
-                 weak_ptr_factory_.GetWeakPtr(), callback);
 
-  scheduler_->ScheduleOperation(base::Bind(
-      &CacheStorageCache::WriteSideDataImpl, weak_ptr_factory_.GetWeakPtr(),
-      pending_callback, url, expected_response_time, buffer, buf_len));
+  // GetUsageAndQuota is called before entering a scheduled operation since it
+  // can call Size, another scheduled operation.
+  quota_manager_proxy_->GetUsageAndQuota(
+      base::ThreadTaskRunnerHandle::Get().get(), origin_,
+      storage::kStorageTypeTemporary,
+      base::Bind(&CacheStorageCache::WriteSideDataDidGetQuota,
+                 weak_ptr_factory_.GetWeakPtr(), callback, url,
+                 expected_response_time, buffer, buf_len));
 }
 
 void CacheStorageCache::BatchOperation(
     const std::vector<CacheStorageBatchOperation>& operations,
     const ErrorCallback& callback) {
   if (!LazyInitialize()) {
-    callback.Run(CACHE_STORAGE_ERROR_STORAGE);
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_STORAGE));
+    return;
+  }
+
+  // Estimate the required size of the put operations. The size of the deletes
+  // is unknown and not considered.
+  int64_t space_required = 0;
+  for (const auto& operation : operations) {
+    if (operation.operation_type == CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT) {
+      space_required +=
+          operation.request.blob_size + operation.response.blob_size;
+    }
+  }
+  if (space_required > 0) {
+    // GetUsageAndQuota is called before entering a scheduled operation since it
+    // can call Size, another scheduled operation. This is racy. The decision
+    // to commit is made before the scheduled Put operation runs. By the time
+    // Put runs, the cache might already be full and the origin will be larger
+    // than it's supposed to be.
+    quota_manager_proxy_->GetUsageAndQuota(
+        base::ThreadTaskRunnerHandle::Get().get(), origin_,
+        storage::kStorageTypeTemporary,
+        base::Bind(&CacheStorageCache::BatchDidGetUsageAndQuota,
+                   weak_ptr_factory_.GetWeakPtr(), operations, callback,
+                   space_required));
+    return;
+  }
+
+  BatchDidGetUsageAndQuota(operations, callback, 0 /* space_required */,
+                           storage::kQuotaStatusOk, 0 /* usage */,
+                           0 /* quota */);
+}
+
+void CacheStorageCache::BatchDidGetUsageAndQuota(
+    const std::vector<CacheStorageBatchOperation>& operations,
+    const ErrorCallback& callback,
+    int64_t space_required,
+    storage::QuotaStatusCode status_code,
+    int64_t usage,
+    int64_t quota) {
+  if (status_code != storage::kQuotaStatusOk ||
+      space_required > quota - usage) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_QUOTA_EXCEEDED));
     return;
   }
 
@@ -463,16 +509,13 @@
     return;
   }
 
-  if (initializing_) {
-    // Note that Size doesn't use the scheduler, see header comments for why.
-    pending_size_callbacks_.push_back(callback);
-    return;
-  }
+  SizeCallback pending_callback =
+      base::Bind(&CacheStorageCache::PendingSizeCallback,
+                 weak_ptr_factory_.GetWeakPtr(), callback);
 
-  // Run immediately so that we don't deadlock on
-  // CacheStorageCache::PutDidDelete's call to
-  // quota_manager_proxy_->GetUsageAndQuota.
-  SizeImpl(callback);
+  scheduler_->ScheduleOperation(base::Bind(&CacheStorageCache::SizeImpl,
+                                           weak_ptr_factory_.GetWeakPtr(),
+                                           pending_callback));
 }
 
 void CacheStorageCache::GetSizeThenClose(const SizeCallback& callback) {
@@ -776,6 +819,30 @@
   MatchAllProcessNextEntry(std::move(context), iter + 1);
 }
 
+void CacheStorageCache::WriteSideDataDidGetQuota(
+    const ErrorCallback& callback,
+    const GURL& url,
+    base::Time expected_response_time,
+    scoped_refptr<net::IOBuffer> buffer,
+    int buf_len,
+    storage::QuotaStatusCode status_code,
+    int64_t usage,
+    int64_t quota) {
+  if (status_code != storage::kQuotaStatusOk || (buf_len > quota - usage)) {
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_QUOTA_EXCEEDED));
+    return;
+  }
+
+  ErrorCallback pending_callback =
+      base::Bind(&CacheStorageCache::PendingErrorCallback,
+                 weak_ptr_factory_.GetWeakPtr(), callback);
+
+  scheduler_->ScheduleOperation(base::Bind(
+      &CacheStorageCache::WriteSideDataImpl, weak_ptr_factory_.GetWeakPtr(),
+      pending_callback, url, expected_response_time, buffer, buf_len));
+}
+
 void CacheStorageCache::WriteSideDataImpl(const ErrorCallback& callback,
                                           const GURL& url,
                                           base::Time expected_response_time,
@@ -787,27 +854,6 @@
     return;
   }
 
-  quota_manager_proxy_->GetUsageAndQuota(
-      base::ThreadTaskRunnerHandle::Get().get(), origin_,
-      storage::kStorageTypeTemporary,
-      base::Bind(&CacheStorageCache::WriteSideDataDidGetUsageAndQuota,
-                 weak_ptr_factory_.GetWeakPtr(), callback, url,
-                 expected_response_time, buffer, buf_len));
-}
-
-void CacheStorageCache::WriteSideDataDidGetUsageAndQuota(
-    const ErrorCallback& callback,
-    const GURL& url,
-    base::Time expected_response_time,
-    scoped_refptr<net::IOBuffer> buffer,
-    int buf_len,
-    storage::QuotaStatusCode status_code,
-    int64_t usage,
-    int64_t quota) {
-  if (status_code != storage::kQuotaStatusOk || quota - usage < buf_len) {
-    callback.Run(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED);
-    return;
-  }
   std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr(
       new disk_cache::Entry*());
   disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
@@ -962,31 +1008,6 @@
     return;
   }
 
-  quota_manager_proxy_->GetUsageAndQuota(
-      base::ThreadTaskRunnerHandle::Get().get(), origin_,
-      storage::kStorageTypeTemporary,
-      base::Bind(&CacheStorageCache::PutDidGetUsageAndQuota,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 base::Passed(std::move(put_context))));
-}
-
-void CacheStorageCache::PutDidGetUsageAndQuota(
-    std::unique_ptr<PutContext> put_context,
-    storage::QuotaStatusCode status_code,
-    int64_t usage,
-    int64_t quota) {
-  if (backend_state_ != BACKEND_OPEN) {
-    put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
-    return;
-  }
-
-  if (status_code != storage::kQuotaStatusOk) {
-    put_context->callback.Run(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED);
-    return;
-  }
-
-  put_context->available_bytes = quota - usage;
-
   std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr(
       new disk_cache::Entry*());
   disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
@@ -1058,12 +1079,6 @@
   scoped_refptr<net::StringIOBuffer> buffer(
       new net::StringIOBuffer(std::move(serialized)));
 
-  int64_t bytes_to_write = buffer->size() + put_context->response->blob_size;
-  if (put_context->available_bytes < bytes_to_write) {
-    put_context->callback.Run(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED);
-    return;
-  }
-
   // Get a temporary copy of the entry pointer before passing it in base::Bind.
   disk_cache::Entry* temp_entry_ptr = put_context->cache_entry.get();
 
@@ -1439,10 +1454,6 @@
                        ? BACKEND_OPEN
                        : BACKEND_CLOSED;
 
-  for (const SizeCallback& callback : pending_size_callbacks_)
-    SizeImpl(callback);
-  pending_size_callbacks_.clear();
-
   UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult",
                             cache_create_error, CACHE_STORAGE_ERROR_LAST + 1);
 
diff --git a/content/browser/cache_storage/cache_storage_cache.h b/content/browser/cache_storage/cache_storage_cache.h
index 879cae2..4b3a72e 100644
--- a/content/browser/cache_storage/cache_storage_cache.h
+++ b/content/browser/cache_storage/cache_storage_cache.h
@@ -41,8 +41,8 @@
 
 // Represents a ServiceWorker Cache as seen in
 // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ The
-// asynchronous methods are executed serially (except for Size). Callbacks to
-// the public functions will be called so long as the cache object lives.
+// asynchronous methods are executed serially. Callbacks to the public functions
+// will be called so long as the cache object lives.
 class CONTENT_EXPORT CacheStorageCache
     : public base::RefCounted<CacheStorageCache> {
  public:
@@ -115,6 +115,13 @@
   // http://crbug.com/486637
   void BatchOperation(const std::vector<CacheStorageBatchOperation>& operations,
                       const ErrorCallback& callback);
+  void BatchDidGetUsageAndQuota(
+      const std::vector<CacheStorageBatchOperation>& operations,
+      const ErrorCallback& callback,
+      int64_t space_required,
+      storage::QuotaStatusCode status_code,
+      int64_t usage,
+      int64_t quota);
   void BatchDidOneOperation(const base::Closure& barrier_closure,
                             ErrorCallback* callback,
                             CacheStorageError error);
@@ -128,11 +135,7 @@
   // will exit early. Close should only be called once per CacheStorageCache.
   void Close(const base::Closure& callback);
 
-  // The size of the cache's contents. This runs in parallel with other Cache
-  // operations. This is because QuotaManager is a dependency of the Put
-  // operation and QuotaManager calls Size. If the cache isn't yet initialized,
-  // runs immediately after initialization, before any pending operations in the
-  // scheduler are run.
+  // The size of the cache's contents.
   void Size(const SizeCallback& callback);
 
   // Gets the cache's size, closes the backend, and then runs |callback| with
@@ -213,6 +216,15 @@
                                std::unique_ptr<CacheMetadata> metadata);
 
   // WriteSideData callbacks
+  void WriteSideDataDidGetQuota(const ErrorCallback& callback,
+                                const GURL& url,
+                                base::Time expected_response_time,
+                                scoped_refptr<net::IOBuffer> buffer,
+                                int buf_len,
+                                storage::QuotaStatusCode status_code,
+                                int64_t usage,
+                                int64_t quota);
+
   void WriteSideDataImpl(const ErrorCallback& callback,
                          const GURL& url,
                          base::Time expected_response_time,
@@ -354,7 +366,6 @@
   base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
   BackendState backend_state_ = BACKEND_UNINITIALIZED;
   std::unique_ptr<CacheStorageScheduler> scheduler_;
-  std::vector<SizeCallback> pending_size_callbacks_;
   bool initializing_ = false;
   int64_t cache_size_ = 0;
 
diff --git a/content/browser/cache_storage/cache_storage_cache_unittest.cc b/content/browser/cache_storage/cache_storage_cache_unittest.cc
index 084d50e2..7dae860 100644
--- a/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -1165,9 +1165,9 @@
   ASSERT_TRUE(Delete(body_request_));
 }
 
-TEST_P(CacheStorageCacheTestP, WriteSideData_QuotaExeeded) {
+TEST_P(CacheStorageCacheTestP, WriteSideData_QuotaExceeded) {
   mock_quota_manager_->SetQuota(GURL(kOrigin), storage::kStorageTypeTemporary,
-                                1024 * 1024);
+                                1024 * 1023);
   base::Time response_time(base::Time::Now());
   ServiceWorkerResponse response;
   response.response_time = response_time;
@@ -1287,7 +1287,7 @@
 TEST_P(CacheStorageCacheTestP, PutObeysQuotaLimits) {
   mock_quota_manager_->SetQuota(GURL(kOrigin), storage::kStorageTypeTemporary,
                                 0);
-  EXPECT_FALSE(Put(no_body_request_, no_body_response_));
+  EXPECT_FALSE(Put(body_request_, body_response_));
   EXPECT_EQ(CACHE_STORAGE_ERROR_QUOTA_EXCEEDED, callback_error_);
 }
 
@@ -1307,41 +1307,6 @@
   EXPECT_EQ(0, Size());
 }
 
-TEST_P(CacheStorageCacheTestP, SizeOperationsArePrioritized) {
-  // Test that pending size operations (those waiting for initialization) run
-  // before other scheduler operations.
-  cache_->set_delay_backend_creation(true);  // Delay cache initialization
-
-  CacheStorageBatchOperation operation;
-  operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT;
-  operation.request = body_request_;
-  operation.response = body_response_;
-
-  callback_error_ = CACHE_STORAGE_ERROR_NOT_FOUND;
-  base::RunLoop run_loop;
-  // Start a put operation that blocks on initialization.
-  cache_->BatchOperation(std::vector<CacheStorageBatchOperation>(1, operation),
-                         base::Bind(&CacheStorageCacheTest::ErrorTypeCallback,
-                                    base::Unretained(this), &run_loop));
-
-  // Next start a size operation that also blocks on initialization.
-  bool size_callback_called = false;
-  cache_->Size(base::Bind(&CacheStorageCacheTest::SizeCallback,
-                          base::Unretained(this), nullptr,
-                          &size_callback_called));
-
-  base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(size_callback_called);
-  EXPECT_EQ(CACHE_STORAGE_ERROR_NOT_FOUND, callback_error_);
-
-  // Finish initialization. The Size operation should complete before Put gets
-  // to run as Size has priority. See crbug.com/605663.
-  cache_->ContinueCreateBackend();
-  run_loop.Run();
-  EXPECT_TRUE(size_callback_called);
-  EXPECT_EQ(CACHE_STORAGE_OK, callback_error_);
-}
-
 TEST_P(CacheStorageCacheTestP, GetSizeThenClose) {
   EXPECT_TRUE(Put(body_request_, body_response_));
   int64_t cache_size = Size();
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
index 3e7015c..5d7a304 100644
--- a/content/browser/child_process_launcher.cc
+++ b/content/browser/child_process_launcher.cc
@@ -198,11 +198,8 @@
     }
   };
   maybe_register(
-      kV8NativesDataDescriptor32,
-      gin::V8Initializer::GetOpenNativesFileForChildProcesses(&region, true));
-  maybe_register(
-      kV8NativesDataDescriptor64,
-      gin::V8Initializer::GetOpenNativesFileForChildProcesses(&region, false));
+      kV8NativesDataDescriptor,
+      gin::V8Initializer::GetOpenNativesFileForChildProcesses(&region));
   maybe_register(
       kV8SnapshotDataDescriptor32,
       gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(&region, true));
diff --git a/content/browser/loader/DEPS b/content/browser/loader/DEPS
index 3d395e59..d94a60c 100644
--- a/content/browser/loader/DEPS
+++ b/content/browser/loader/DEPS
@@ -92,9 +92,6 @@
     "-content",
     "+content/browser/loader/power_save_block_resource_throttle.h",
     "+content/public/browser/resource_throttle.h",
-
-    # TODO: these all have to be removed.
-    "+content/public/browser/browser_thread.h",
   ],
   "resource_dispatcher_host_impl\.(cc|h)": [
     "-content",
diff --git a/content/browser/loader/power_save_block_resource_throttle.cc b/content/browser/loader/power_save_block_resource_throttle.cc
index 97ceac0..1af02c5 100644
--- a/content/browser/loader/power_save_block_resource_throttle.cc
+++ b/content/browser/loader/power_save_block_resource_throttle.cc
@@ -4,7 +4,6 @@
 
 #include "content/browser/loader/power_save_block_resource_throttle.h"
 
-#include "content/public/browser/browser_thread.h"
 #include "device/power_save_blocker/power_save_blocker.h"
 
 namespace content {
@@ -16,8 +15,12 @@
 }  // namespace
 
 PowerSaveBlockResourceThrottle::PowerSaveBlockResourceThrottle(
-    const std::string& host)
-    : host_(host) {}
+    const std::string& host,
+    scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner)
+    : host_(host),
+      ui_task_runner_(ui_task_runner),
+      blocking_task_runner_(blocking_task_runner) {}
 
 PowerSaveBlockResourceThrottle::~PowerSaveBlockResourceThrottle() {
 }
@@ -44,8 +47,7 @@
   power_save_blocker_.reset(new device::PowerSaveBlocker(
       device::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension,
       device::PowerSaveBlocker::kReasonOther, "Uploading data to " + host_,
-      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
-      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
+      ui_task_runner_, blocking_task_runner_));
 }
 
 }  // namespace content
diff --git a/content/browser/loader/power_save_block_resource_throttle.h b/content/browser/loader/power_save_block_resource_throttle.h
index 7e4b9ba..67b8a9f 100644
--- a/content/browser/loader/power_save_block_resource_throttle.h
+++ b/content/browser/loader/power_save_block_resource_throttle.h
@@ -10,6 +10,9 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "base/single_thread_task_runner.h"
 #include "base/timer/timer.h"
 #include "content/public/browser/resource_throttle.h"
 
@@ -22,7 +25,10 @@
 // This ResourceThrottle blocks power save until large upload request finishes.
 class PowerSaveBlockResourceThrottle : public ResourceThrottle {
  public:
-  explicit PowerSaveBlockResourceThrottle(const std::string& host);
+  PowerSaveBlockResourceThrottle(
+      const std::string& host,
+      scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
+      scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner);
   ~PowerSaveBlockResourceThrottle() override;
 
   // ResourceThrottle overrides:
@@ -36,6 +42,8 @@
   const std::string host_;
   base::OneShotTimer timer_;
   std::unique_ptr<device::PowerSaveBlocker> power_save_blocker_;
+  scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> blocking_task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(PowerSaveBlockResourceThrottle);
 };
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 11c590b..8fcd0de 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1708,8 +1708,10 @@
 
   if (request->has_upload()) {
     // Block power save while uploading data.
-    throttles.push_back(
-        new PowerSaveBlockResourceThrottle(request->url().host()));
+    throttles.push_back(new PowerSaveBlockResourceThrottle(
+        request->url().host(),
+        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
   }
 
   // TODO(ricea): Stop looking this up so much.
diff --git a/content/browser/media/media_browsertest.cc b/content/browser/media/media_browsertest.cc
index 4f677992..2f52ad5 100644
--- a/content/browser/media/media_browsertest.cc
+++ b/content/browser/media/media_browsertest.cc
@@ -127,7 +127,13 @@
 }
 
 #if defined(USE_PROPRIETARY_CODECS)
-IN_PROC_BROWSER_TEST_P(MediaTest, VideoBearMp4) {
+// Crashes on Mac only.  http://crbug.com/621857
+#if defined(OS_MACOSX)
+#define MAYBE_VideoBearMp4 DISABLED_VideoBearMp4
+#else
+#define MAYBE_VideoBearMp4 VideoBearMp4
+#endif
+IN_PROC_BROWSER_TEST_P(MediaTest, MAYBE_VideoBearMp4) {
   PlayVideo("bear.mp4", GetParam());
 }
 
@@ -135,7 +141,13 @@
   PlayVideo("bear-320x180-hi10p.mp4", GetParam());
 }
 
-IN_PROC_BROWSER_TEST_P(MediaTest, VideoBearSilentMp4) {
+// Crashes on Mac only.  http://crbug.com/621857
+#if defined(OS_MACOSX)
+#define MAYBE_VideoBearSilentMp4 DISABLED_VideoBearSilentMp4
+#else
+#define MAYBE_VideoBearSilentMp4 VideoBearSilentMp4
+#endif
+IN_PROC_BROWSER_TEST_P(MediaTest, MAYBE_VideoBearSilentMp4) {
   PlayVideo("bear_silent.mp4", GetParam());
 }
 
diff --git a/content/browser/renderer_host/OWNERS b/content/browser/renderer_host/OWNERS
index b3ee6fc..86f4fdf 100644
--- a/content/browser/renderer_host/OWNERS
+++ b/content/browser/renderer_host/OWNERS
@@ -30,3 +30,7 @@
 per-file render_sandbox_host_linux.*=jorgelo@chromium.org
 per-file sandbox_ipc_linux.*=jln@chromium.org
 per-file sandbox_ipc_linux.*=jorgelo@chromium.org
+
+# WebSQL
+per-file database_*=jsbell@chromium.org
+per-file database_*=michaeln@chromium.org
diff --git a/content/browser/renderer_host/database_message_filter.cc b/content/browser/renderer_host/database_message_filter.cc
index 5f9a8ae5d..8bf1adb 100644
--- a/content/browser/renderer_host/database_message_filter.cc
+++ b/content/browser/renderer_host/database_message_filter.cc
@@ -25,6 +25,7 @@
 #include "storage/browser/quota/quota_manager_proxy.h"
 #include "storage/common/database/database_identifier.h"
 #include "third_party/sqlite/sqlite3.h"
+#include "url/origin.h"
 
 #if defined(OS_POSIX)
 #include "base/file_descriptor_posix.h"
@@ -42,6 +43,10 @@
 const int kNumDeleteRetries = 2;
 const int kDelayDeleteRetryMs = 100;
 
+bool IsOriginValid(const url::Origin& origin) {
+  return !origin.unique();
+}
+
 }  // namespace
 
 DatabaseMessageFilter::DatabaseMessageFilter(
@@ -249,10 +254,17 @@
 }
 
 void DatabaseMessageFilter::OnDatabaseGetSpaceAvailable(
-    const std::string& origin_identifier, IPC::Message* reply_msg) {
+    const url::Origin& origin,
+    IPC::Message* reply_msg) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   DCHECK(db_tracker_->quota_manager_proxy());
 
+  if (!IsOriginValid(origin)) {
+    bad_message::ReceivedBadMessage(
+        this, bad_message::DBMF_INVALID_ORIGIN_ON_GET_SPACE);
+    return;
+  }
+
   QuotaManager* quota_manager =
       db_tracker_->quota_manager_proxy()->quota_manager();
   if (!quota_manager) {
@@ -267,10 +279,9 @@
   TRACE_EVENT0("io", "DatabaseMessageFilter::OnDatabaseGetSpaceAvailable");
 
   quota_manager->GetUsageAndQuota(
-      storage::GetOriginFromIdentifier(origin_identifier),
-      storage::kStorageTypeTemporary,
-      base::Bind(
-          &DatabaseMessageFilter::OnDatabaseGetUsageAndQuota, this, reply_msg));
+      GURL(origin.Serialize()), storage::kStorageTypeTemporary,
+      base::Bind(&DatabaseMessageFilter::OnDatabaseGetUsageAndQuota, this,
+                 reply_msg));
 }
 
 void DatabaseMessageFilter::OnDatabaseGetUsageAndQuota(
@@ -298,36 +309,45 @@
 }
 
 void DatabaseMessageFilter::OnDatabaseOpened(
-    const std::string& origin_identifier,
+    const url::Origin& origin,
     const base::string16& database_name,
     const base::string16& description,
     int64_t estimated_size) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
 
-  if (!storage::IsValidOriginIdentifier(origin_identifier)) {
+  if (!IsOriginValid(origin)) {
     bad_message::ReceivedBadMessage(this,
                                     bad_message::DBMF_INVALID_ORIGIN_ON_OPEN);
     return;
   }
 
-  UMA_HISTOGRAM_BOOLEAN(
-      "websql.OpenDatabase",
-      IsOriginSecure(storage::GetOriginFromIdentifier(origin_identifier)));
+  GURL origin_url(origin.Serialize());
+  UMA_HISTOGRAM_BOOLEAN("websql.OpenDatabase", IsOriginSecure(origin_url));
 
   int64_t database_size = 0;
+  std::string origin_identifier(storage::GetIdentifierFromOrigin(origin_url));
   db_tracker_->DatabaseOpened(origin_identifier, database_name, description,
                               estimated_size, &database_size);
+
   database_connections_.AddConnection(origin_identifier, database_name);
-  Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
-                                  database_size));
+  Send(new DatabaseMsg_UpdateSize(origin, database_name, database_size));
 }
 
 void DatabaseMessageFilter::OnDatabaseModified(
-    const std::string& origin_identifier,
+    const url::Origin& origin,
     const base::string16& database_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
-  if (!database_connections_.IsDatabaseOpened(
-          origin_identifier, database_name)) {
+
+  if (!IsOriginValid(origin)) {
+    bad_message::ReceivedBadMessage(
+        this, bad_message::DBMF_INVALID_ORIGIN_ON_MODIFIED);
+    return;
+  }
+
+  std::string origin_identifier(
+      storage::GetIdentifierFromOrigin(GURL(origin.Serialize())));
+  if (!database_connections_.IsDatabaseOpened(origin_identifier,
+                                              database_name)) {
     bad_message::ReceivedBadMessage(this,
                                     bad_message::DBMF_DB_NOT_OPEN_ON_MODIFY);
     return;
@@ -337,9 +357,18 @@
 }
 
 void DatabaseMessageFilter::OnDatabaseClosed(
-    const std::string& origin_identifier,
+    const url::Origin& origin,
     const base::string16& database_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+
+  if (!IsOriginValid(origin)) {
+    bad_message::ReceivedBadMessage(this,
+                                    bad_message::DBMF_INVALID_ORIGIN_ON_CLOSED);
+    return;
+  }
+
+  std::string origin_identifier(
+      storage::GetIdentifierFromOrigin(GURL(origin.Serialize())));
   if (!database_connections_.IsDatabaseOpened(
           origin_identifier, database_name)) {
     bad_message::ReceivedBadMessage(this,
@@ -352,17 +381,18 @@
 }
 
 void DatabaseMessageFilter::OnHandleSqliteError(
-    const std::string& origin_identifier,
+    const url::Origin& origin,
     const base::string16& database_name,
     int error) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
-  if (!storage::IsValidOriginIdentifier(origin_identifier)) {
+  if (!IsOriginValid(origin)) {
     bad_message::ReceivedBadMessage(
         this, bad_message::DBMF_INVALID_ORIGIN_ON_SQLITE_ERROR);
     return;
   }
-
-  db_tracker_->HandleSqliteError(origin_identifier, database_name, error);
+  db_tracker_->HandleSqliteError(
+      storage::GetIdentifierFromOrigin(GURL(origin.Serialize())), database_name,
+      error);
 }
 
 void DatabaseMessageFilter::OnDatabaseSizeChanged(
@@ -371,8 +401,9 @@
     int64_t database_size) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
   if (database_connections_.IsOriginUsed(origin_identifier)) {
-    Send(new DatabaseMsg_UpdateSize(origin_identifier, database_name,
-                                    database_size));
+    Send(new DatabaseMsg_UpdateSize(
+        url::Origin(storage::GetOriginFromIdentifier(origin_identifier)),
+        database_name, database_size));
   }
 }
 
@@ -380,7 +411,9 @@
     const std::string& origin_identifier,
     const base::string16& database_name) {
   DCHECK_CURRENTLY_ON(BrowserThread::FILE);
-  Send(new DatabaseMsg_CloseImmediately(origin_identifier, database_name));
+  Send(new DatabaseMsg_CloseImmediately(
+      url::Origin(storage::GetOriginFromIdentifier(origin_identifier)),
+      database_name));
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/database_message_filter.h b/content/browser/renderer_host/database_message_filter.h
index 4cf4e92..125dcef 100644
--- a/content/browser/renderer_host/database_message_filter.h
+++ b/content/browser/renderer_host/database_message_filter.h
@@ -15,6 +15,10 @@
 #include "storage/common/database/database_connections.h"
 #include "storage/common/quota/quota_types.h"
 
+namespace url {
+class Origin;
+}  // namespace url
+
 namespace content {
 
 class DatabaseMessageFilter : public BrowserMessageFilter,
@@ -56,7 +60,7 @@
                              bool* success);
 
   // Quota message handler (io thread)
-  void OnDatabaseGetSpaceAvailable(const std::string& origin_identifier,
+  void OnDatabaseGetSpaceAvailable(const url::Origin& origin,
                                    IPC::Message* reply_msg);
   void OnDatabaseGetUsageAndQuota(IPC::Message* reply_msg,
                                   storage::QuotaStatusCode status,
@@ -64,15 +68,15 @@
                                   int64_t quota);
 
   // Database tracker message handlers (file thread)
-  void OnDatabaseOpened(const std::string& origin_identifier,
+  void OnDatabaseOpened(const url::Origin& origin,
                         const base::string16& database_name,
                         const base::string16& description,
                         int64_t estimated_size);
-  void OnDatabaseModified(const std::string& origin_identifier,
+  void OnDatabaseModified(const url::Origin& origin,
                           const base::string16& database_name);
-  void OnDatabaseClosed(const std::string& origin_identifier,
+  void OnDatabaseClosed(const url::Origin& origin,
                         const base::string16& database_name);
-  void OnHandleSqliteError(const std::string& origin_identifier,
+  void OnHandleSqliteError(const url::Origin& origin,
                            const base::string16& database_name,
                            int error);
 
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
index 417bf88..edbed1a 100644
--- a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
+++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
@@ -25,9 +25,6 @@
       binding_(this, std::move(request)) {}
 
 OffscreenCanvasSurfaceImpl::~OffscreenCanvasSurfaceImpl() {
-  if (surface_factory_) {
-    surface_factory_->DestroyAll();
-  }
 }
 
 void OffscreenCanvasSurfaceImpl::GetSurfaceId(
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
index f044331..1204067 100644
--- a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -334,7 +334,10 @@
 
 void P2PSocketDispatcherHost::DoGetNetworkList() {
   net::NetworkInterfaceList list;
-  net::GetNetworkList(&list, net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES);
+  if (!net::GetNetworkList(&list, net::EXCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES)) {
+    LOG(ERROR) << "GetNetworkList failed.";
+    return;
+  }
   default_ipv4_local_address_ = GetDefaultLocalAddress(AF_INET);
   default_ipv6_local_address_ = GetDefaultLocalAddress(AF_INET6);
   BrowserThread::PostTask(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index bfa723a..909c4883 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -109,8 +109,8 @@
 
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
 #include "content/common/input_messages.h"
-#include "ui/events/linux/text_edit_command_auralinux.h"
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_command_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #endif
 
 using gfx::RectToSkIRect;
diff --git a/content/browser/utility_process_mojo_client_browsertest.cc b/content/browser/utility_process_mojo_client_browsertest.cc
index 8517017d..7ffa80d 100644
--- a/content/browser/utility_process_mojo_client_browsertest.cc
+++ b/content/browser/utility_process_mojo_client_browsertest.cc
@@ -22,9 +22,11 @@
  public:
   void StartMojoService(bool disable_sandbox) {
     mojo_client_.reset(new UtilityProcessMojoClient<mojom::TestMojoService>(
-        base::ASCIIToUTF16("TestMojoProcess"),
+        base::ASCIIToUTF16("TestMojoProcess")));
+
+    mojo_client_->set_error_callback(
         base::Bind(&UtilityProcessMojoClientBrowserTest::OnConnectionError,
-                   base::Unretained(this))));
+                   base::Unretained(this)));
 
     // This test case needs to have the sandbox disabled.
     if (disable_sandbox)
diff --git a/content/child/OWNERS b/content/child/OWNERS
index 62b2db6..3d62269f 100644
--- a/content/child/OWNERS
+++ b/content/child/OWNERS
@@ -1,9 +1,18 @@
 # For Blink API usage
 esprehn@chromium.org
 
+# AppCache
 per-file appcache*=michaeln@chromium.org
 
 # WebSocket
 per-file *websocket*=ricea@chromium.org
 per-file *websocket*=tyoshino@chromium.org
 per-file *websocket*=yhirano@chromium.org
+
+# WebSQL
+per-file database_*=jsbell@chromium.org
+per-file database_*=michaeln@chromium.org
+per-file db_*=jsbell@chromium.org
+per-file db_*=michaeln@chromium.org
+per-file web_database_*=jsbell@chromium.org
+per-file web_database_*=michaeln@chromium.org
diff --git a/content/child/database_util.cc b/content/child/database_util.cc
index 844799e..2dd4754a 100644
--- a/content/child/database_util.cc
+++ b/content/child/database_util.cc
@@ -6,10 +6,12 @@
 
 #include "content/common/database_messages.h"
 #include "ipc/ipc_sync_message_filter.h"
+#include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/sqlite/sqlite3.h"
 
 using blink::Platform;
+using blink::WebSecurityOrigin;
 using blink::WebString;
 
 namespace content {
@@ -56,11 +58,10 @@
 }
 
 long long DatabaseUtil::DatabaseGetSpaceAvailable(
-    const WebString& origin_identifier,
+    const WebSecurityOrigin& origin,
     IPC::SyncMessageFilter* sync_message_filter) {
   int64_t rv = 0LL;
-  sync_message_filter->Send(
-      new DatabaseHostMsg_GetSpaceAvailable(origin_identifier.utf8(), &rv));
+  sync_message_filter->Send(new DatabaseHostMsg_GetSpaceAvailable(origin, &rv));
   return rv;
 }
 
diff --git a/content/child/database_util.h b/content/child/database_util.h
index adeb3972d..df6e545 100644
--- a/content/child/database_util.h
+++ b/content/child/database_util.h
@@ -34,7 +34,7 @@
       const blink::WebString& vfs_file_name,
       IPC::SyncMessageFilter* sync_message_filter);
   static long long DatabaseGetSpaceAvailable(
-      const blink::WebString& origin_identifier,
+      const blink::WebSecurityOrigin& origin,
       IPC::SyncMessageFilter* sync_message_filter);
   static bool DatabaseSetFileSize(const blink::WebString& vfs_file_name,
                                   int64_t size,
diff --git a/content/child/db_message_filter.cc b/content/child/db_message_filter.cc
index 9e65a38..5c4045df 100644
--- a/content/child/db_message_filter.cc
+++ b/content/child/db_message_filter.cc
@@ -10,23 +10,13 @@
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/web/WebDatabase.h"
+#include "url/origin.h"
 
 using blink::WebSecurityOrigin;
 using blink::WebString;
 
 namespace content {
 
-namespace {
-
-// TODO(jsbell): Pass url::Origin over IPC instead of database identifier/GURL.
-// https://crbug.com/591482
-WebSecurityOrigin OriginFromIdentifier(const std::string& identifier) {
-  return WebSecurityOrigin::create(
-      storage::GetOriginFromIdentifier(identifier));
-}
-
-}  // namespace
-
 DBMessageFilter::DBMessageFilter() {
 }
 
@@ -45,31 +35,29 @@
   return handled;
 }
 
-void DBMessageFilter::OnDatabaseUpdateSize(const std::string& origin_identifier,
+void DBMessageFilter::OnDatabaseUpdateSize(const url::Origin& origin,
                                            const base::string16& database_name,
                                            int64_t database_size) {
-  blink::WebDatabase::updateDatabaseSize(
-      OriginFromIdentifier(origin_identifier), database_name, database_size);
+  DCHECK(!origin.unique());
+  blink::WebDatabase::updateDatabaseSize(origin, database_name, database_size);
 }
 
-void DBMessageFilter::OnDatabaseUpdateSpaceAvailable(
-    const std::string& origin_identifier,
-    int64_t space_available) {
-  blink::WebDatabase::updateSpaceAvailable(
-      OriginFromIdentifier(origin_identifier), space_available);
+void DBMessageFilter::OnDatabaseUpdateSpaceAvailable(const url::Origin& origin,
+                                                     int64_t space_available) {
+  DCHECK(!origin.unique());
+  blink::WebDatabase::updateSpaceAvailable(origin, space_available);
 }
 
-void DBMessageFilter::OnDatabaseResetSpaceAvailable(
-    const std::string& origin_identifier) {
-  blink::WebDatabase::resetSpaceAvailable(
-      OriginFromIdentifier(origin_identifier));
+void DBMessageFilter::OnDatabaseResetSpaceAvailable(const url::Origin& origin) {
+  DCHECK(!origin.unique());
+  blink::WebDatabase::resetSpaceAvailable(origin);
 }
 
 void DBMessageFilter::OnDatabaseCloseImmediately(
-    const std::string& origin_identifier,
+    const url::Origin& origin,
     const base::string16& database_name) {
-  blink::WebDatabase::closeDatabaseImmediately(
-      OriginFromIdentifier(origin_identifier), database_name);
+  DCHECK(!origin.unique());
+  blink::WebDatabase::closeDatabaseImmediately(origin, database_name);
 }
 
 }  // namespace content
diff --git a/content/child/db_message_filter.h b/content/child/db_message_filter.h
index fb1875e26..55cc2a7 100644
--- a/content/child/db_message_filter.h
+++ b/content/child/db_message_filter.h
@@ -10,6 +10,10 @@
 #include "base/strings/string16.h"
 #include "ipc/message_filter.h"
 
+namespace url {
+class Origin;
+}  // namespace url
+
 namespace content {
 
 // Receives database messages from the browser process and processes them on the
@@ -25,13 +29,13 @@
   ~DBMessageFilter() override {}
 
  private:
-  void OnDatabaseUpdateSize(const std::string& origin_identifier,
+  void OnDatabaseUpdateSize(const url::Origin& origin,
                             const base::string16& database_name,
                             int64_t database_size);
-  void OnDatabaseUpdateSpaceAvailable(const std::string& origin_identifier,
+  void OnDatabaseUpdateSpaceAvailable(const url::Origin& origin,
                                       int64_t space_available);
-  void OnDatabaseResetSpaceAvailable(const std::string& origin_identifier);
-  void OnDatabaseCloseImmediately(const std::string& origin_identifier,
+  void OnDatabaseResetSpaceAvailable(const url::Origin& origin);
+  void OnDatabaseCloseImmediately(const url::Origin& origin,
                                   const base::string16& database_name);
 };
 
diff --git a/content/child/web_database_observer_impl.cc b/content/child/web_database_observer_impl.cc
index 368e0a56..bddc9e1 100644
--- a/content/child/web_database_observer_impl.cc
+++ b/content/child/web_database_observer_impl.cc
@@ -81,27 +81,26 @@
     const WebString& database_name,
     const WebString& database_display_name,
     unsigned long estimated_size) {
-  const std::string origin_identifier = GetIdentifierFromOrigin(origin);
-  open_connections_->AddOpenConnection(origin_identifier, database_name);
+  open_connections_->AddOpenConnection(GetIdentifierFromOrigin(origin),
+                                       database_name);
   sender_->Send(new DatabaseHostMsg_Opened(
-      origin_identifier, database_name, database_display_name, estimated_size));
+      origin, database_name, database_display_name, estimated_size));
 }
 
 void WebDatabaseObserverImpl::databaseModified(const WebSecurityOrigin& origin,
                                                const WebString& database_name) {
-  sender_->Send(new DatabaseHostMsg_Modified(GetIdentifierFromOrigin(origin),
-                                             database_name));
+  sender_->Send(new DatabaseHostMsg_Modified(origin, database_name));
 }
 
 void WebDatabaseObserverImpl::databaseClosed(const WebSecurityOrigin& origin,
                                              const WebString& database_name) {
   DCHECK(!main_thread_task_runner_->RunsTasksOnCurrentThread());
-  const std::string origin_identifier = GetIdentifierFromOrigin(origin);
   main_thread_task_runner_->PostTask(
       FROM_HERE,
       base::Bind(base::IgnoreResult(&IPC::SyncMessageFilter::Send), sender_,
-                 new DatabaseHostMsg_Closed(origin_identifier, database_name)));
-  open_connections_->RemoveOpenConnection(origin_identifier, database_name);
+                 new DatabaseHostMsg_Closed(origin, database_name)));
+  open_connections_->RemoveOpenConnection(GetIdentifierFromOrigin(origin),
+                                          database_name);
 }
 
 void WebDatabaseObserverImpl::reportOpenDatabaseResult(
@@ -191,8 +190,8 @@
   // a unnecessary ipc traffic, this method can get called at a fairly
   // high frequency (per-sqlstatement).
   if (error == SQLITE_CORRUPT || error == SQLITE_NOTADB) {
-    sender_->Send(new DatabaseHostMsg_HandleSqliteError(
-        GetIdentifierFromOrigin(origin), database_name, error));
+    sender_->Send(
+        new DatabaseHostMsg_HandleSqliteError(origin, database_name, error));
   }
 }
 
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index e21dac1..79140384 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -61,6 +61,7 @@
     "//media",
     "//media:shared_memory_support",
     "//media/base/ipc",
+    "//media/capture",
     "//media/gpu/ipc/client",
     "//media/gpu/ipc/common",
     "//media/midi",
diff --git a/content/common/OWNERS b/content/common/OWNERS
index 574417d..7724169 100644
--- a/content/common/OWNERS
+++ b/content/common/OWNERS
@@ -23,8 +23,8 @@
 per-file *_messages.cc=set noparent
 per-file *_messages.cc=file://ipc/SECURITY_OWNERS
 
-per-file *param_traits*.*=set noparent
-per-file *param_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
 
 per-file *font_config_ipc_linux*=set noparent
 per-file *font_config_ipc_linux*=file://ipc/SECURITY_OWNERS
diff --git a/content/common/android/OWNERS b/content/common/android/OWNERS
index 211a551e..9e94ab2 100644
--- a/content/common/android/OWNERS
+++ b/content/common/android/OWNERS
@@ -1,8 +1,8 @@
 tedchoc@chromium.org
 yfriedman@chromium.org
 
-per-file *_message*.h=set noparent
-per-file *_message*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
 
 per-file *_messages.cc=set noparent
 per-file *_messages.cc=file://ipc/SECURITY_OWNERS
diff --git a/content/common/database_messages.h b/content/common/database_messages.h
index 0e5c1f9..fa0ea26 100644
--- a/content/common/database_messages.h
+++ b/content/common/database_messages.h
@@ -9,6 +9,7 @@
 #include "ipc/ipc_message_macros.h"
 #include "ipc/ipc_param_traits.h"
 #include "ipc/ipc_platform_file.h"
+#include "url/origin.h"
 
 #define IPC_MESSAGE_START DatabaseMsgStart
 
@@ -16,22 +17,22 @@
 
 // Notifies the child process of the new database size
 IPC_MESSAGE_CONTROL3(DatabaseMsg_UpdateSize,
-                     std::string /* the origin */,
+                     url::Origin /* the origin */,
                      base::string16 /* the database name */,
                      int64_t /* the new database size */)
 
 // Notifies the child process of the new space available
 IPC_MESSAGE_CONTROL2(DatabaseMsg_UpdateSpaceAvailable,
-                     std::string /* the origin */,
+                     url::Origin /* the origin */,
                      int64_t /* space available to origin */)
 
 // Notifies the child process to reset it's cached value for the origin.
 IPC_MESSAGE_CONTROL1(DatabaseMsg_ResetSpaceAvailable,
-                     std::string /* the origin */)
+                     url::Origin /* the origin */)
 
 // Asks the child process to close a database immediately
 IPC_MESSAGE_CONTROL2(DatabaseMsg_CloseImmediately,
-                     std::string /* the origin */,
+                     url::Origin /* the origin */,
                      base::string16 /* the database name */)
 
 // Database messages sent from the renderer to the browser.
@@ -60,7 +61,7 @@
 
 // Asks the browser process for the amount of space available to an origin
 IPC_SYNC_MESSAGE_CONTROL1_1(DatabaseHostMsg_GetSpaceAvailable,
-                            std::string /* origin identifier */,
+                            url::Origin /* origin */,
                             int64_t /* remaining space available */)
 
 // Asks the browser set the size of a DB file
@@ -71,23 +72,23 @@
 
 // Notifies the browser process that a new database has been opened
 IPC_MESSAGE_CONTROL4(DatabaseHostMsg_Opened,
-                     std::string /* origin identifier */,
+                     url::Origin /* origin */,
                      base::string16 /* database name */,
                      base::string16 /* database description */,
                      int64_t /* estimated size */)
 
 // Notifies the browser process that a database might have been modified
 IPC_MESSAGE_CONTROL2(DatabaseHostMsg_Modified,
-                     std::string /* origin identifier */,
+                     url::Origin /* origin */,
                      base::string16 /* database name */)
 
 // Notifies the browser process that a database is about to close
 IPC_MESSAGE_CONTROL2(DatabaseHostMsg_Closed,
-                     std::string /* origin identifier */,
+                     url::Origin /* origin */,
                      base::string16 /* database name */)
 
 // Sent when a sqlite error indicates the database is corrupt.
 IPC_MESSAGE_CONTROL3(DatabaseHostMsg_HandleSqliteError,
-                     std::string /* origin identifier */,
+                     url::Origin /* origin */,
                      base::string16 /* database name */,
-                     int  /* error */)
+                     int /* error */)
diff --git a/content/common/mojo/OWNERS b/content/common/mojo/OWNERS
index cc00f26..9216e7a 100644
--- a/content/common/mojo/OWNERS
+++ b/content/common/mojo/OWNERS
@@ -1,5 +1,5 @@
-per-file *_message*.h=set noparent
-per-file *_message*.h=file://ipc/SECURITY_OWNERS
+per-file *_messages*.h=set noparent
+per-file *_messages*.h=file://ipc/SECURITY_OWNERS
 
-per-file *param_traits*.*=set noparent
-per-file *param_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index 4aa5076e..bb3fd6ed 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -2010,7 +2010,7 @@
     ['use_udev == 1', {
       'dependencies': [
         '../device/udev_linux/udev.gyp:udev_linux',
-        '../media/media.gyp:media',
+        '../media/capture/capture.gyp:capture',
       ],
     }, {
       'sources!': [
diff --git a/content/content_common.gypi b/content/content_common.gypi
index 55e8cac30..9a17f6d 100644
--- a/content/content_common.gypi
+++ b/content/content_common.gypi
@@ -17,6 +17,7 @@
     '../ipc/ipc.gyp:ipc',
     '../ipc/mojo/ipc_mojo.gyp:ipc_mojo',
     '../media/base/ipc/media_base_ipc.gyp:media_base_ipc',
+    '../media/capture/capture.gyp:capture',
     '../media/media.gyp:media',
     '../media/media.gyp:media_gpu',
     '../media/media.gyp:shared_memory_support',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index e1a1d6e..d1ad79c 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -855,6 +855,7 @@
         '../gpu/gpu.gyp:gpu_ipc_service_test_support',
         '../ipc/mojo/ipc_mojo.gyp:ipc_mojo',
         '../media/blink/media_blink.gyp:media_blink',
+        '../media/capture/capture.gyp:capture',
         '../media/media.gyp:media',
         '../media/midi/midi.gyp:midi',
         '../mojo/mojo_edk.gyp:mojo_common_test_support',
@@ -1837,6 +1838,7 @@
             '../base/base.gyp:base_javatests',
             '../base/base.gyp:base_java_test_support',
             '../device/battery/battery.gyp:device_battery_javatests',
+            '../media/capture/capture.gyp:capture_java',
             '../media/media.gyp:media_java',
             '../media/media.gyp:media_test_support',
             '../mojo/mojo_public.gyp:mojo_public_test_interfaces',
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java b/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java
index 3a2fcca..117d6b8a 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/TracingControllerAndroidTest.java
@@ -10,18 +10,23 @@
 import android.test.suitebuilder.annotation.MediumTest;
 
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.content_shell_apk.ContentShellActivity;
 import org.chromium.content_shell_apk.ContentShellTestBase;
 
 import java.io.File;
 
+/**
+ * Test suite for TracingControllerAndroid.
+ */
 public class TracingControllerAndroidTest extends ContentShellTestBase {
 
     private static final long TIMEOUT_MILLIS = scaleTimeout(30 * 1000);
 
     @MediumTest
     @Feature({"GPU"})
+    @DisabledTest(message = "crbug.com/621956")
     public void testTraceFileCreation() throws Exception {
         ContentShellActivity activity = launchContentShellWithUrl("about:blank");
         waitForActiveShellToBeDoneLoading();
diff --git a/content/public/browser/utility_process_mojo_client.h b/content/public/browser/utility_process_mojo_client.h
index 3bbe2e9..5de3ff7 100644
--- a/content/public/browser/utility_process_mojo_client.h
+++ b/content/public/browser/utility_process_mojo_client.h
@@ -28,10 +28,7 @@
 template <class MojoInterface>
 class UtilityProcessMojoClient {
  public:
-  UtilityProcessMojoClient(const base::string16& process_name,
-                           const base::Closure& on_error_callback)
-      : on_error_callback_(on_error_callback) {
-    DCHECK(!on_error_callback_.is_null());
+  explicit UtilityProcessMojoClient(const base::string16& process_name) {
     helper_.reset(new Helper(process_name));
   }
 
@@ -39,6 +36,12 @@
     BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, helper_.release());
   }
 
+  // Sets the error callback. A valid callback must be set before calling
+  // Start().
+  void set_error_callback(const base::Closure& on_error_callback) {
+    on_error_callback_ = on_error_callback;
+  }
+
   // Disables the sandbox in the utility process.
   void set_disable_sandbox() {
     DCHECK(!start_called_);
@@ -48,14 +51,13 @@
   // Starts the utility process and connect to the remote Mojo service.
   void Start() {
     DCHECK(thread_checker_.CalledOnValidThread());
+    DCHECK(!on_error_callback_.is_null());
     DCHECK(!start_called_);
 
     start_called_ = true;
 
     mojo::InterfaceRequest<MojoInterface> req = mojo::GetProxy(&service_);
-
     service_.set_connection_error_handler(on_error_callback_);
-
     helper_->Start(MojoInterface::Name_, req.PassMessagePipe());
   }
 
diff --git a/content/public/common/OWNERS b/content/public/common/OWNERS
index dfefce7..d278610 100644
--- a/content/public/common/OWNERS
+++ b/content/public/common/OWNERS
@@ -1,5 +1,5 @@
-per-file *param_traits*.*=set noparent
-per-file *param_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
 
 # DirectWrite
 per-file dwrite_font_platform_win.h=scottmg@chromium.org
diff --git a/content/public/common/content_descriptors.h b/content/public/common/content_descriptors.h
index ff282ae..fa67a0f 100644
--- a/content/public/common/content_descriptors.h
+++ b/content/public/common/content_descriptors.h
@@ -16,13 +16,11 @@
   kMojoIPCChannel,
 
 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
+  kV8NativesDataDescriptor,
 #if defined(OS_ANDROID)
-  kV8NativesDataDescriptor32,
   kV8SnapshotDataDescriptor32,
-  kV8NativesDataDescriptor64,
   kV8SnapshotDataDescriptor64,
 #else
-  kV8NativesDataDescriptor,
   kV8SnapshotDataDescriptor,
 #endif
 #endif
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 374ceff..139a800 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -60,6 +60,7 @@
     "//jingle:jingle_glue",
     "//media",
     "//media/blink",
+    "//media/capture",
     "//media/gpu",
     "//media/gpu/ipc/client",
     "//media/gpu/ipc/common",
diff --git a/content/renderer/manifest/manifest_parser_unittest.cc b/content/renderer/manifest/manifest_parser_unittest.cc
index a19e81e..5a9c9460 100644
--- a/content/renderer/manifest/manifest_parser_unittest.cc
+++ b/content/renderer/manifest/manifest_parser_unittest.cc
@@ -29,9 +29,9 @@
   ~ManifestParserTest() override {}
 
   Manifest ParseManifestWithURLs(const base::StringPiece& data,
-                                 const GURL& document_url,
-                                 const GURL& manifest_url) {
-    ManifestParser parser(data, document_url, manifest_url);
+                                 const GURL& manifest_url,
+                                 const GURL& document_url) {
+    ManifestParser parser(data, manifest_url, document_url);
     parser.Parse();
     std::vector<ManifestDebugInfo::Error> errors;
     parser.TakeErrors(&errors);
@@ -44,7 +44,7 @@
 
   Manifest ParseManifest(const base::StringPiece& data) {
     return ParseManifestWithURLs(
-        data, default_document_url, default_manifest_url);
+        data, default_manifest_url, default_document_url);
   }
 
   const std::vector<std::string>& errors() const {
@@ -512,7 +512,7 @@
   {
     Manifest manifest = ParseManifest("{ \"icons\": [ { \"src\": \"\" } ] }");
     EXPECT_EQ(manifest.icons.size(), 1u);
-    EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/index.html");
+    EXPECT_EQ(manifest.icons[0].src.spec(), "http://foo.com/manifest.json");
     EXPECT_FALSE(manifest.IsEmpty());
     EXPECT_EQ(0u, GetErrorCount());
   }
diff --git a/content/renderer/mus/render_widget_mus_connection.cc b/content/renderer/mus/render_widget_mus_connection.cc
index ccd8d90..e146893 100644
--- a/content/renderer/mus/render_widget_mus_connection.cc
+++ b/content/renderer/mus/render_widget_mus_connection.cc
@@ -12,7 +12,7 @@
 #include "components/mus/public/cpp/output_surface.h"
 #include "components/mus/public/cpp/surfaces/surfaces_utils.h"
 #include "components/mus/public/interfaces/command_buffer.mojom.h"
-#include "components/mus/public/interfaces/compositor_frame.mojom.h"
+#include "components/mus/public/interfaces/surface.mojom.h"
 #include "components/mus/public/interfaces/window_tree.mojom.h"
 #include "content/public/common/mojo_shell_connection.h"
 #include "content/renderer/mus/compositor_mus_connection.h"
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 68195283..3a26166 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1677,6 +1677,9 @@
     bound_graphics_2d_platform_->set_viewport_to_dip_scale(
         viewport_to_dip_scale_);
 
+  module_->renderer_ppapi_host()->set_viewport_to_dip_scale(
+      viewport_to_dip_scale_);
+
   // During the first view update, initialize the throttler.
   if (!sent_initial_did_change_view_) {
     if (is_flash_plugin_ && RenderThread::Get()) {
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.cc b/content/renderer/pepper/renderer_ppapi_host_impl.cc
index 8eea55b3..178aa02 100644
--- a/content/renderer/pepper/renderer_ppapi_host_impl.cc
+++ b/content/renderer/pepper/renderer_ppapi_host_impl.cc
@@ -213,8 +213,10 @@
     // dedicated window.  So, do not offset the point.
     return pt;
   }
-  return gfx::Point(pt.x() + plugin_instance->view_data().rect.point.x,
-                    pt.y() + plugin_instance->view_data().rect.point.y);
+  return gfx::Point((pt.x() + plugin_instance->view_data().rect.point.x) /
+                        viewport_to_dip_scale_,
+                    (pt.y() + plugin_instance->view_data().rect.point.y) /
+                        viewport_to_dip_scale_);
 }
 
 IPC::PlatformFileForTransit RendererPpapiHostImpl::ShareHandleWithRemote(
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.h b/content/renderer/pepper/renderer_ppapi_host_impl.h
index 8cb6a5d..668b9c22 100644
--- a/content/renderer/pepper/renderer_ppapi_host_impl.h
+++ b/content/renderer/pepper/renderer_ppapi_host_impl.h
@@ -104,6 +104,11 @@
       const override;
   GURL GetDocumentURL(PP_Instance pp_instance) const override;
 
+  void set_viewport_to_dip_scale(float viewport_to_dip_scale) {
+    DCHECK_LT(0, viewport_to_dip_scale_);
+    viewport_to_dip_scale_ = viewport_to_dip_scale;
+  }
+
  private:
   RendererPpapiHostImpl(PluginModule* module,
                         ppapi::proxy::HostDispatcher* dispatcher,
@@ -136,6 +141,9 @@
   // Whether this is a host for external plugins.
   bool is_external_plugin_host_;
 
+  // The scale between the viewport and dip.
+  float viewport_to_dip_scale_ = 1.0f;
+
   DISALLOW_COPY_AND_ASSIGN(RendererPpapiHostImpl);
 };
 
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index e4466112..8c8005e 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -71,7 +71,6 @@
 #include "content/child/worker_thread_registry.h"
 #include "content/common/child_process_messages.h"
 #include "content/common/content_constants_internal.h"
-#include "content/common/database_messages.h"
 #include "content/common/dom_storage/dom_storage_messages.h"
 #include "content/common/frame_messages.h"
 #include "content/common/gpu/client/context_provider_command_buffer.h"
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 675bc4b..fadb703 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -45,7 +45,6 @@
 #include "content/child/webmessageportchannel_impl.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/content_switches_internal.h"
-#include "content/common/database_messages.h"
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/common/drag_messages.h"
 #include "content/common/frame_messages.h"
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 8363b50..04bda6c9 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -651,11 +651,8 @@
 
 long long RendererBlinkPlatformImpl::databaseGetSpaceAvailableForOrigin(
     const blink::WebSecurityOrigin& origin) {
-  // TODO(jsbell): Pass url::Origin over IPC instead of database
-  // identifier/GURL. https://crbug.com/591482
-  return DatabaseUtil::DatabaseGetSpaceAvailable(WebString::fromUTF8(
-      storage::GetIdentifierFromOrigin(WebSecurityOriginToGURL(origin))),
-      sync_message_filter_.get());
+  return DatabaseUtil::DatabaseGetSpaceAvailable(origin,
+                                                 sync_message_filter_.get());
 }
 
 bool RendererBlinkPlatformImpl::databaseSetFileSize(
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index a6575d2..79782aa 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -74,6 +74,7 @@
     "//ipc:test_support",
     "//ipc/mojo",
     "//media",
+    "//media/capture",
     "//mojo/edk/system",
     "//mojo/edk/test:test_support",
     "//net:test_support",
@@ -185,6 +186,7 @@
 
   if (is_android) {
     deps += [
+      "//media/capture/video/android:android",
       "//ui/android",
       "//ui/shell_dialogs",
     ]
@@ -669,6 +671,7 @@
     "//media:test_support",
     "//media/audio:test_support",
     "//media/base:test_support",
+    "//media/capture",
     "//media/midi:midi",
     "//mojo/edk/test:test_support",
     "//mojo/public/cpp/bindings",
diff --git a/dbus/bus.cc b/dbus/bus.cc
index 8f78745..d6e2c5b6 100644
--- a/dbus/bus.cc
+++ b/dbus/bus.cc
@@ -13,6 +13,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread.h"
 #include "base/threading/thread_restrictions.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "dbus/exported_object.h"
 #include "dbus/message.h"
@@ -202,8 +203,8 @@
   dbus_threads_init_default();
   // The origin message loop is unnecessary if the client uses synchronous
   // functions only.
-  if (base::MessageLoop::current())
-    origin_task_runner_ = base::MessageLoop::current()->task_runner();
+  if (base::ThreadTaskRunnerHandle::IsSet())
+    origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
 }
 
 Bus::~Bus() {
diff --git a/extensions/browser/crx_file_info.h b/extensions/browser/crx_file_info.h
index 49a5341..17b348a 100644
--- a/extensions/browser/crx_file_info.h
+++ b/extensions/browser/crx_file_info.h
@@ -31,4 +31,4 @@
 
 }  // namespace extensions
 
-#endif  // EXTENSIONS_BROWSER_CRX_FILE_H_
+#endif  // EXTENSIONS_BROWSER_CRX_FILE_INFO_H_
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc
index deed151..e06c132 100644
--- a/gin/v8_initializer.cc
+++ b/gin/v8_initializer.cc
@@ -63,22 +63,19 @@
   return opened_files[file];
 }
 
+const char kNativesFileName[] = "natives_blob.bin";
+
 #if defined(OS_ANDROID)
-const char kNativesFileName64[] = "natives_blob_64.bin";
 const char kSnapshotFileName64[] = "snapshot_blob_64.bin";
-const char kNativesFileName32[] = "natives_blob_32.bin";
 const char kSnapshotFileName32[] = "snapshot_blob_32.bin";
 
 #if defined(__LP64__)
-#define kNativesFileName kNativesFileName64
 #define kSnapshotFileName kSnapshotFileName64
 #else
-#define kNativesFileName kNativesFileName32
 #define kSnapshotFileName kSnapshotFileName32
 #endif
 
 #else  // defined(OS_ANDROID)
-const char kNativesFileName[] = "natives_blob.bin";
 const char kSnapshotFileName[] = "snapshot_blob.bin";
 #endif  // defined(OS_ANDROID)
 
@@ -388,17 +385,6 @@
 
 #if defined(OS_ANDROID)
 // static
-base::PlatformFile V8Initializer::GetOpenNativesFileForChildProcesses(
-    base::MemoryMappedFile::Region* region_out,
-    bool abi_32_bit) {
-  const char* natives_file =
-      abi_32_bit ? kNativesFileName32 : kNativesFileName64;
-  const OpenedFileMap::mapped_type& opened = OpenFileIfNecessary(natives_file);
-  *region_out = opened.second;
-  return opened.first;
-}
-
-// static
 base::PlatformFile V8Initializer::GetOpenSnapshotFileForChildProcesses(
     base::MemoryMappedFile::Region* region_out,
     bool abi_32_bit) {
@@ -410,9 +396,9 @@
 }
 
 // static
-base::FilePath V8Initializer::GetNativesFilePath(bool abi_32_bit) {
+base::FilePath V8Initializer::GetNativesFilePath() {
   base::FilePath path;
-  GetV8FilePath(abi_32_bit ? kNativesFileName32 : kNativesFileName64, &path);
+  GetV8FilePath(kNativesFileName, &path);
   return path;
 }
 
diff --git a/gin/v8_initializer.h b/gin/v8_initializer.h
index 4c03480..7d16c3eb 100644
--- a/gin/v8_initializer.h
+++ b/gin/v8_initializer.h
@@ -67,14 +67,11 @@
       base::MemoryMappedFile::Region* region_out);
 
 #if defined(OS_ANDROID)
-  static base::PlatformFile GetOpenNativesFileForChildProcesses(
-      base::MemoryMappedFile::Region* region_out,
-      bool abi_32_bit);
   static base::PlatformFile GetOpenSnapshotFileForChildProcesses(
       base::MemoryMappedFile::Region* region_out,
       bool abi_32_bit);
 
-  static base::FilePath GetNativesFilePath(bool abi_32_bit);
+  static base::FilePath GetNativesFilePath();
   static base::FilePath GetSnapshotFilePath(bool abi_32_bit);
 #endif
 
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
index fe297287..364f76d 100644
--- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
+++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
@@ -374,6 +374,10 @@
 
   main_request_context_->set_cert_verifier(
       io_thread_globals->cert_verifier.get());
+  main_request_context_->set_ct_policy_enforcer(
+      io_thread_globals->ct_policy_enforcer.get());
+  main_request_context_->set_cert_transparency_verifier(
+      io_thread_globals->cert_transparency_verifier.get());
 
   InitializeInternal(std::move(network_delegate), profile_params_.get(),
                      protocol_handlers);
diff --git a/ios/chrome/browser/ios_chrome_io_thread.h b/ios/chrome/browser/ios_chrome_io_thread.h
index ed4d28d..d1527cb 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.h
+++ b/ios/chrome/browser/ios_chrome_io_thread.h
@@ -128,6 +128,7 @@
     std::unique_ptr<net::CookieStore> system_cookie_store;
     std::unique_ptr<net::HttpUserAgentSettings> http_user_agent_settings;
     std::unique_ptr<net::NetworkQualityEstimator> network_quality_estimator;
+    std::unique_ptr<net::CTPolicyEnforcer> ct_policy_enforcer;
   };
 
   // |net_log| must either outlive the IOSChromeIOThread or be NULL.
diff --git a/ios/chrome/browser/ios_chrome_io_thread.mm b/ios/chrome/browser/ios_chrome_io_thread.mm
index 85c3bed7..97721b6 100644
--- a/ios/chrome/browser/ios_chrome_io_thread.mm
+++ b/ios/chrome/browser/ios_chrome_io_thread.mm
@@ -359,7 +359,7 @@
   // Add built-in logs
   ct_verifier->AddLogs(ct_logs);
 
-  params_.ct_policy_enforcer = new net::CTPolicyEnforcer;
+  globals_->ct_policy_enforcer.reset(new net::CTPolicyEnforcer());
 
   globals_->ssl_config_service = GetSSLConfigService();
 
@@ -530,6 +530,7 @@
   context->set_http_auth_handler_factory(
       globals->http_auth_handler_factory.get());
   context->set_proxy_service(globals->system_proxy_service.get());
+  context->set_ct_policy_enforcer(globals->ct_policy_enforcer.get());
 
   net::URLRequestJobFactoryImpl* system_job_factory =
       new net::URLRequestJobFactoryImpl();
diff --git a/ios/crnet/crnet_environment.mm b/ios/crnet/crnet_environment.mm
index b971a9b..c4daef8 100644
--- a/ios/crnet/crnet_environment.mm
+++ b/ios/crnet/crnet_environment.mm
@@ -23,6 +23,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/path_service.h"
+#include "base/single_thread_task_runner.h"
 #include "base/threading/worker_pool.h"
 #include "components/prefs/json_pref_store.h"
 #include "components/prefs/pref_filter.h"
@@ -178,8 +179,7 @@
 
 void CrNetEnvironment::StartNetLogInternal(
     base::FilePath::StringType file_name, bool log_bytes) {
-  DCHECK(base::MessageLoop::current() ==
-         file_user_blocking_thread_->message_loop());
+  DCHECK(file_user_blocking_thread_->task_runner()->BelongsToCurrentThread());
   DCHECK(file_name.length());
   DCHECK(net_log_);
 
@@ -212,8 +212,7 @@
 }
 
 void CrNetEnvironment::StopNetLogInternal() {
-  DCHECK(base::MessageLoop::current() ==
-         file_user_blocking_thread_->message_loop());
+  DCHECK(file_user_blocking_thread_->task_runner()->BelongsToCurrentThread());
   if (net_log_observer_) {
     net_log_observer_->StopObserving(nullptr);
     net_log_observer_.reset();
@@ -243,8 +242,7 @@
 }
 
 void CrNetEnvironment::CloseAllSpdySessionsInternal() {
-  DCHECK(base::MessageLoop::current() ==
-         network_io_thread_->message_loop());
+  DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
 
   net::HttpNetworkSession* http_network_session =
       GetHttpNetworkSession(GetMainContextGetter()->GetURLRequestContext());
@@ -328,7 +326,7 @@
 }
 
 void CrNetEnvironment::ConfigureSdchOnNetworkThread() {
-  DCHECK(base::MessageLoop::current() == network_io_thread_->message_loop());
+  DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
   net::URLRequestContext* context =
       main_context_getter_->GetURLRequestContext();
 
@@ -353,7 +351,7 @@
 }
 
 void CrNetEnvironment::InitializeOnNetworkThread() {
-  DCHECK(base::MessageLoop::current() == network_io_thread_->message_loop());
+  DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
 
   ConfigureSdchOnNetworkThread();
 
diff --git a/ios/web/public/test/web_test_with_web_state.h b/ios/web/public/test/web_test_with_web_state.h
index 1287910..f2578374 100644
--- a/ios/web/public/test/web_test_with_web_state.h
+++ b/ios/web/public/test/web_test_with_web_state.h
@@ -11,8 +11,6 @@
 #include "ios/web/public/test/web_test.h"
 #include "url/gurl.h"
 
-@class CRWWebController;
-
 namespace web {
 
 class WebState;
@@ -71,9 +69,6 @@
   NSString* CreateLoadCheck();
   // The web state for testing.
   std::unique_ptr<WebState> web_state_;
-  // The web controller for testing.
-  // TODO(crbug.com/619076): Remove this ivar.
-  base::WeakNSObject<CRWWebController> webController_;
 };
 
 }  // namespace web
diff --git a/ios/web/public/test/web_test_with_web_state.mm b/ios/web/public/test/web_test_with_web_state.mm
index 32a0353..55f964a3 100644
--- a/ios/web/public/test/web_test_with_web_state.mm
+++ b/ios/web/public/test/web_test_with_web_state.mm
@@ -25,6 +25,15 @@
 }
 @end
 
+namespace {
+// Returns CRWWebController for the given |web_state|.
+CRWWebController* GetWebController(web::WebState* web_state) {
+  web::WebStateImpl* web_state_impl =
+      static_cast<web::WebStateImpl*>(web_state);
+  return web_state_impl->GetWebController();
+}
+}  // namespace
+
 namespace web {
 
 WebTestWithWebState::WebTestWithWebState() {}
@@ -38,11 +47,10 @@
   std::unique_ptr<WebStateImpl> web_state(new WebStateImpl(GetBrowserState()));
   web_state->GetNavigationManagerImpl().InitializeSession(nil, nil, NO, 0);
   web_state->SetWebUsageEnabled(true);
-  webController_.reset(web_state->GetWebController());
   web_state_.reset(web_state.release());
 
   // Force generation of child views; necessary for some tests.
-  [webController_ triggerPendingLoad];
+  [GetWebController(web_state_.get()) triggerPendingLoad];
   s_html_load_count = 0;
 }
 
@@ -81,28 +89,28 @@
 void WebTestWithWebState::LoadURL(const GURL& url) {
   // First step is to ensure that the web controller has finished any previous
   // page loads so the new load is not confused.
-  while ([webController_ loadPhase] != PAGE_LOADED)
+  while ([GetWebController(web_state()) loadPhase] != PAGE_LOADED)
     WaitForBackgroundTasks();
   id originalMockDelegate =
       [OCMockObject niceMockForProtocol:@protocol(CRWWebDelegate)];
   id mockDelegate =
       [[WebDelegateMock alloc] initWithRepresentedObject:originalMockDelegate];
-  id existingDelegate = webController_.get().delegate;
-  webController_.get().delegate = mockDelegate;
+  id existingDelegate = GetWebController(web_state()).delegate;
+  GetWebController(web_state()).delegate = mockDelegate;
 
   web::NavigationManagerImpl& navManager =
-      [webController_ webStateImpl]->GetNavigationManagerImpl();
+      [GetWebController(web_state()) webStateImpl]->GetNavigationManagerImpl();
   navManager.InitializeSession(@"name", nil, NO, 0);
   [navManager.GetSessionController() addPendingEntry:url
                                             referrer:web::Referrer()
                                           transition:ui::PAGE_TRANSITION_TYPED
                                    rendererInitiated:NO];
 
-  [webController_ loadCurrentURL];
-  while ([webController_ loadPhase] != PAGE_LOADED)
+  [GetWebController(web_state()) loadCurrentURL];
+  while ([GetWebController(web_state()) loadPhase] != PAGE_LOADED)
     WaitForBackgroundTasks();
-  webController_.get().delegate = existingDelegate;
-  [[webController_ view] layoutIfNeeded];
+  GetWebController(web_state()).delegate = existingDelegate;
+  [web_state()->GetView() layoutIfNeeded];
 }
 
 void WebTestWithWebState::WaitForBackgroundTasks() {
@@ -139,11 +147,12 @@
 
 NSString* WebTestWithWebState::EvaluateJavaScriptAsString(NSString* script) {
   __block base::scoped_nsobject<NSString> evaluationResult;
-  [webController_ evaluateJavaScript:script
-                 stringResultHandler:^(NSString* result, NSError*) {
-                   DCHECK([result isKindOfClass:[NSString class]]);
-                   evaluationResult.reset([result copy]);
-                 }];
+  [GetWebController(web_state())
+       evaluateJavaScript:script
+      stringResultHandler:^(NSString* result, NSError*) {
+        DCHECK([result isKindOfClass:[NSString class]]);
+        evaluationResult.reset([result copy]);
+      }];
   base::test::ios::WaitUntilCondition(^bool() {
     return evaluationResult;
   });
@@ -153,11 +162,11 @@
 id WebTestWithWebState::ExecuteJavaScript(NSString* script) {
   __block base::scoped_nsprotocol<id> executionResult;
   __block bool executionCompleted = false;
-  [webController_ executeJavaScript:script
-                  completionHandler:^(id result, NSError*) {
-                    executionResult.reset([result copy]);
-                    executionCompleted = true;
-                  }];
+  [GetWebController(web_state()) executeJavaScript:script
+                                 completionHandler:^(id result, NSError*) {
+                                   executionResult.reset([result copy]);
+                                   executionCompleted = true;
+                                 }];
   base::test::ios::WaitUntilCondition(^{
     return executionCompleted;
   });
@@ -178,7 +187,7 @@
   if ([inner_html rangeOfString:load_check].location == NSNotFound) {
     web_state_->SetWebUsageEnabled(false);
     web_state_->SetWebUsageEnabled(true);
-    [webController_ triggerPendingLoad];
+    [GetWebController(web_state()) triggerPendingLoad];
     return true;
   }
   return false;
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index fada4cd..46f58a9 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -1707,10 +1707,12 @@
   // Transfer time is registered so that further transitions within the time
   // envelope are not also registered as links.
   _lastTransferTimeInSeconds = CFAbsoluteTimeGetCurrent();
-  // Before changing phases, the delegate should be informed that any existing
-  // request is being cancelled before completion.
-  [self loadCancelled];
-  DCHECK(_loadPhase == web::PAGE_LOADED);
+  if (!(transition & ui::PAGE_TRANSITION_IS_REDIRECT_MASK)) {
+    // Before changing phases, the delegate should be informed that any existing
+    // request is being cancelled before completion.
+    [self loadCancelled];
+    DCHECK(_loadPhase == web::PAGE_LOADED);
+  }
 
   _loadPhase = web::LOAD_REQUESTED;
   _lastRegisteredRequestURL = requestURL;
diff --git a/ios/web/web_thread_impl.cc b/ios/web/web_thread_impl.cc
index e371cd8c..370295f 100644
--- a/ios/web/web_thread_impl.cc
+++ b/ios/web/web_thread_impl.cc
@@ -373,8 +373,7 @@
   base::AutoLock lock(globals.lock);
   DCHECK(identifier >= 0 && identifier < ID_COUNT);
   return globals.threads[identifier] &&
-         globals.threads[identifier]->message_loop() ==
-             base::MessageLoop::current();
+         globals.threads[identifier]->task_runner()->BelongsToCurrentThread();
 }
 
 // static
diff --git a/jingle/glue/proxy_resolving_client_socket.cc b/jingle/glue/proxy_resolving_client_socket.cc
index cc31edb..45dfee2 100644
--- a/jingle/glue/proxy_resolving_client_socket.cc
+++ b/jingle/glue/proxy_resolving_client_socket.cc
@@ -11,6 +11,7 @@
 #include "base/bind_helpers.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "net/base/io_buffer.h"
 #include "net/base/ip_address.h"
 #include "net/base/load_flags.h"
@@ -152,9 +153,7 @@
     // We defer execution of ProcessProxyResolveDone instead of calling it
     // directly here for simplicity. From the caller's point of view,
     // the connect always happens asynchronously.
-    base::MessageLoop* message_loop = base::MessageLoop::current();
-    CHECK(message_loop);
-    message_loop->PostTask(
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::Bind(&ProxyResolvingClientSocket::ProcessProxyResolveDone,
                    weak_factory_.GetWeakPtr(), status));
@@ -308,9 +307,7 @@
   // In both cases we want to post ProcessProxyResolveDone (in the error case
   // we might still want to fall back a direct connection).
   if (rv != net::ERR_IO_PENDING) {
-    base::MessageLoop* message_loop = base::MessageLoop::current();
-    CHECK(message_loop);
-    message_loop->PostTask(
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::Bind(&ProxyResolvingClientSocket::ProcessProxyResolveDone,
                    weak_factory_.GetWeakPtr(), rv));
diff --git a/jingle/notifier/base/xmpp_connection.cc b/jingle/notifier/base/xmpp_connection.cc
index d50adb0..efa62bc 100644
--- a/jingle/notifier/base/xmpp_connection.cc
+++ b/jingle/notifier/base/xmpp_connection.cc
@@ -8,8 +8,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/logging.h"
-#include "base/message_loop/message_loop.h"
 #include "base/strings/string_piece.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "jingle/glue/chrome_async_socket.h"
 #include "jingle/glue/task_pump.h"
 #include "jingle/glue/xmpp_client_socket_factory.h"
@@ -82,13 +82,12 @@
   DCHECK(CalledOnValidThread());
   ClearClient();
   task_pump_->Stop();
-  base::MessageLoop* current_message_loop = base::MessageLoop::current();
-  CHECK(current_message_loop);
   // We do this because XmppConnection may get destroyed as a result
   // of a signal from XmppClient.  If we delete |task_pump_| here, bad
   // things happen when the stack pops back up to the XmppClient's
   // (which is deleted by |task_pump_|) function.
-  current_message_loop->DeleteSoon(FROM_HERE, task_pump_.release());
+  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
+                                                  task_pump_.release());
 }
 
 void XmppConnection::OnStateChange(buzz::XmppEngine::State state) {
diff --git a/media/BUILD.gn b/media/BUILD.gn
index fb4c400..99b66f6e 100644
--- a/media/BUILD.gn
+++ b/media/BUILD.gn
@@ -337,8 +337,6 @@
     deps += [
       "//media/base/android",
       "//media/base/android:media_jni_headers",
-      "//media/capture/video/android:capture_java",
-      "//media/capture/video/android:capture_jni_headers",
     ]
 
     # Only 64 bit builds are using android-21 NDK library, check common.gypi
@@ -362,6 +360,11 @@
 
   if (is_mac) {
     public_deps += [ "//media/base/mac" ]
+    libs += [
+      "CoreFoundation.framework",
+      "CoreGraphics.framework",
+      "Foundation.framework",
+    ]
   }
 
   if (is_ios) {
@@ -370,12 +373,6 @@
 
   if (is_win) {
     deps += [ "//media/base/win" ]
-    libs += [
-      "mf.lib",
-      "mfplat.lib",
-      "mfreadwrite.lib",
-      "mfuuid.lib",
-    ]
   }
 
   if (proprietary_codecs) {
@@ -462,7 +459,6 @@
     ":shared_memory_support",
     "//media/audio",
     "//media/base",
-    "//media/capture",
     "//third_party/opus",
   ]
 
@@ -597,6 +593,8 @@
     "//media/audio:unittests",
     "//media/base:test_support",
     "//media/base:unittests",
+
+    # TODO(mcasas): Remove the capture sources after https://crbug.com/618718.
     "//media/capture:unittests",
     "//media/test:pipeline_integration_tests",
     "//skia",  # Direct dependency required to inherit config.
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn
index 792dbe79..7db6c40 100644
--- a/media/base/BUILD.gn
+++ b/media/base/BUILD.gn
@@ -401,6 +401,14 @@
     "//testing/gmock",
     "//ui/gfx:test_support",
   ]
+  if (is_android) {
+    deps += [
+      # Needed to register capture Java/Jni objects. TODO(mcasas): Remove when
+      # the dependency to capture is not needed, see https://crbug.com/618718.
+      "//media/capture",
+      "//media/capture/video/android",
+    ]
+  }
 }
 
 source_set("unittests") {
diff --git a/media/base/win/BUILD.gn b/media/base/win/BUILD.gn
index 49559bac..a90f7c94 100644
--- a/media/base/win/BUILD.gn
+++ b/media/base/win/BUILD.gn
@@ -4,19 +4,32 @@
 
 assert(is_win)
 
-source_set("win") {
+component("win") {
+  defines = [ "MF_INITIALIZER_IMPLEMENTATION" ]
   set_sources_assignment_filter([])
   sources = [
     "mf_initializer.cc",
     "mf_initializer.h",
+    "mf_initializer_export.h",
   ]
   set_sources_assignment_filter(sources_assignment_filter)
   configs += [
+    # TODO(jschuh): https://crbug.com/167187 fix size_t to int truncations.
+    "//build/config/compiler:no_size_t_to_int_warning",
     "//media:media_config",
-    "//media:media_implementation",
   ]
   deps = [
     "//base",
     "//media:shared_memory_support",
   ]
+  libs = [
+    "mf.lib",
+    "mfplat.lib",
+    "mfreadwrite.lib",
+  ]
+  ldflags = [
+    "/DELAYLOAD:mf.dll",
+    "/DELAYLOAD:mfplat.dll",
+    "/DELAYLOAD:mfreadwrite.dll",
+  ]
 }
diff --git a/media/base/win/mf_initializer.h b/media/base/win/mf_initializer.h
index 4c10d6a..eadc39cc 100644
--- a/media/base/win/mf_initializer.h
+++ b/media/base/win/mf_initializer.h
@@ -5,13 +5,13 @@
 #ifndef MEDIA_BASE_WIN_MF_INITIALIZER_H_
 #define MEDIA_BASE_WIN_MF_INITIALIZER_H_
 
-#include "media/base/media_export.h"
+#include "media/base/win/mf_initializer_export.h"
 
 namespace media {
 
 // Makes sure MFStartup() is called exactly once, and that this call is paired
 // by a call to MFShutdown().
-MEDIA_EXPORT void InitializeMediaFoundation();
+MF_INITIALIZER_EXPORT void InitializeMediaFoundation();
 
 }  // namespace media
 
diff --git a/media/base/win/mf_initializer_export.h b/media/base/win/mf_initializer_export.h
new file mode 100644
index 0000000..d81391d0
--- /dev/null
+++ b/media/base/win/mf_initializer_export.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_BASE_WIN_MF_INITIALIZER_EXPORT_H_
+#define MEDIA_BASE_WIN_MF_INITIALIZER_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(MF_INITIALIZER_IMPLEMENTATION)
+#define MF_INITIALIZER_EXPORT __declspec(dllexport)
+#else
+#define MF_INITIALIZER_EXPORT __declspec(dllimport)
+#endif  // defined(MF_INITIALIZER_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(MF_INITIALIZER_IMPLEMENTATION)
+#define MF_INITIALIZER_EXPORT __attribute__((visibility("default")))
+#else
+#define MF_INITIALIZER_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define MF_INITIALIZER_EXPORT
+#endif
+
+#endif  // MEDIA_BASE_WIN_MF_INITIALIZER_EXPORT_H_
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn
index f6968116a..619f000 100644
--- a/media/capture/BUILD.gn
+++ b/media/capture/BUILD.gn
@@ -6,8 +6,10 @@
 import("//media/media_options.gni")
 import("//testing/test.gni")
 
-source_set("capture") {
+component("capture") {
+  defines = [ "CAPTURE_IMPLEMENTATION" ]
   sources = [
+    "capture_export.h",
     "content/animated_content_sampler.cc",
     "content/animated_content_sampler.h",
     "content/capture_resolution_chooser.cc",
@@ -25,12 +27,6 @@
     "device_monitor_mac.mm",
     "system_message_window_win.cc",
     "system_message_window_win.h",
-    "video/android/photo_capabilities.cc",
-    "video/android/photo_capabilities.h",
-    "video/android/video_capture_device_android.cc",
-    "video/android/video_capture_device_android.h",
-    "video/android/video_capture_device_factory_android.cc",
-    "video/android/video_capture_device_factory_android.h",
     "video/fake_video_capture_device.cc",
     "video/fake_video_capture_device.h",
     "video/fake_video_capture_device_factory.cc",
@@ -83,20 +79,26 @@
   public_deps = []
   deps = [
     "//base",
-    "//media/base",
+    "//base:i18n",
+    "//media",
     "//skia",
     "//ui/display",
+    "//ui/gfx",
   ]
 
   configs += [
+    # TODO(mcasas): media/base should be a component and not a source_set, but
+    # it depends on parts of media/filters, media/ffmpeg etc. Until then, we
+    # pretend to be inside media.dll and duplicate the few symbols needed, see
+    # https://crbug.com/590017.
     "//media:media_implementation",
-
-    # TODO(mcasas): Fix size_t to int truncation warning-treated-as-errors.
-    "//build/config/compiler:no_size_t_to_int_warning",
   ]
 
   if (is_android) {
-    public_deps += [ "video/android" ]
+    public_deps += [
+      "video/android",
+      "video/android:capture_java",
+    ]
     deps += [ "video/android:capture_jni_headers" ]
   }
 
@@ -105,6 +107,7 @@
     libs = [
       "CoreFoundation.framework",
       "CoreGraphics.framework",
+      "CoreVideo.framework",
       "Foundation.framework",
     ]
   }
@@ -118,22 +121,28 @@
   }
 
   if (is_win) {
-    public_deps += [ "//media/base/win" ]
+    deps += [
+      "//media/base",  # For media_switches.
+      "//media/base/win",
+    ]
     libs = [
       "mf.lib",
       "mfplat.lib",
       "mfreadwrite.lib",
       "mfuuid.lib",
     ]
-
     ldflags = [
       "/DELAYLOAD:mf.dll",
       "/DELAYLOAD:mfplat.dll",
       "/DELAYLOAD:mfreadwrite.dll",
     ]
+
+    # TODO(jschuh): https://crbug.com/167187 fix size_t to int truncations.
+    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
   }
 }
 
+# TODO(mcasas): Make this a test target, https://crbug.com/618718.
 source_set("unittests") {
   testonly = true
 
@@ -150,11 +159,13 @@
   ]
 
   deps = [
-    "//media/base:unittests",
+    ":capture",
     "//testing/gmock",
     "//testing/gtest",
   ]
 
-  # TODO(mcasas): Fix size_t to int truncation warning-treated-as-errors.
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+  if (is_win) {
+    # TODO(jschuh): https://crbug.com/167187 fix size_t to int truncations.
+    configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+  }
 }
diff --git a/media/capture/capture.gyp b/media/capture/capture.gyp
new file mode 100644
index 0000000..d8de2d5
--- /dev/null
+++ b/media/capture/capture.gyp
@@ -0,0 +1,225 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'variables': {
+    'chromium_code': 1,
+    'capture_sources': [
+      'capture_export.h',
+      'content/animated_content_sampler.cc',
+      'content/animated_content_sampler.h',
+      'content/capture_resolution_chooser.cc',
+      'content/capture_resolution_chooser.h',
+      'content/feedback_signal_accumulator.h',
+      'content/screen_capture_device_core.cc',
+      'content/screen_capture_device_core.h',
+      'content/smooth_event_sampler.cc',
+      'content/smooth_event_sampler.h',
+      'content/thread_safe_capture_oracle.cc',
+      'content/thread_safe_capture_oracle.h',
+      'content/video_capture_oracle.cc',
+      'content/video_capture_oracle.h',
+      'device_monitor_mac.h',
+      'device_monitor_mac.mm',
+      'system_message_window_win.cc',
+      'system_message_window_win.h',
+      'video/android/video_capture_device_android.cc',
+      'video/android/video_capture_device_android.h',
+      'video/android/video_capture_device_factory_android.cc',
+      'video/android/video_capture_device_factory_android.h',
+      'video/fake_video_capture_device.cc',
+      'video/fake_video_capture_device.h',
+      'video/fake_video_capture_device_factory.cc',
+      'video/fake_video_capture_device_factory.h',
+      'video/file_video_capture_device.cc',
+      'video/file_video_capture_device.h',
+      'video/file_video_capture_device_factory.cc',
+      'video/file_video_capture_device_factory.h',
+      'video/linux/v4l2_capture_delegate.cc',
+      'video/linux/v4l2_capture_delegate.h',
+      'video/linux/video_capture_device_chromeos.cc',
+      'video/linux/video_capture_device_chromeos.h',
+      'video/linux/video_capture_device_factory_linux.cc',
+      'video/linux/video_capture_device_factory_linux.h',
+      'video/linux/video_capture_device_linux.cc',
+      'video/linux/video_capture_device_linux.h',
+      'video/mac/video_capture_device_avfoundation_mac.h',
+      'video/mac/video_capture_device_avfoundation_mac.mm',
+      'video/mac/video_capture_device_decklink_mac.h',
+      'video/mac/video_capture_device_decklink_mac.mm',
+      'video/mac/video_capture_device_factory_mac.h',
+      'video/mac/video_capture_device_factory_mac.mm',
+      'video/mac/video_capture_device_mac.h',
+      'video/mac/video_capture_device_mac.mm',
+      'video/scoped_result_callback.h',
+      'video/video_capture_device.cc',
+      'video/video_capture_device.h',
+      'video/video_capture_device_factory.cc',
+      'video/video_capture_device_factory.h',
+      'video/video_capture_device_info.cc',
+      'video/video_capture_device_info.h',
+      'video/win/capability_list_win.cc',
+      'video/win/capability_list_win.h',
+      'video/win/filter_base_win.cc',
+      'video/win/filter_base_win.h',
+      'video/win/pin_base_win.cc',
+      'video/win/pin_base_win.h',
+      'video/win/sink_filter_observer_win.h',
+      'video/win/sink_filter_win.cc',
+      'video/win/sink_filter_win.h',
+      'video/win/sink_input_pin_win.cc',
+      'video/win/sink_input_pin_win.h',
+      'video/win/video_capture_device_factory_win.cc',
+      'video/win/video_capture_device_factory_win.h',
+      'video/win/video_capture_device_mf_win.cc',
+      'video/win/video_capture_device_mf_win.h',
+      'video/win/video_capture_device_win.cc',
+      'video/win/video_capture_device_win.h'
+    ],
+
+    'capture_unittests_sources': [
+      'content/animated_content_sampler_unittest.cc',
+      'content/capture_resolution_chooser_unittest.cc',
+      'content/feedback_signal_accumulator_unittest.cc',
+      'content/smooth_event_sampler_unittest.cc',
+      'content/video_capture_oracle_unittest.cc',
+      'system_message_window_win_unittest.cc',
+      'video/fake_video_capture_device_unittest.cc',
+      'video/mac/video_capture_device_factory_mac_unittest.mm',
+      'video/video_capture_device_unittest.cc'
+    ],
+
+    # The following files lack appropriate platform suffixes.
+    'conditions': [
+      ['OS=="linux" and use_udev==1', {
+        'capture_sources': [
+          'device_monitor_udev.cc',
+          'device_monitor_udev.h',
+        ],
+      }],
+    ],
+  },
+
+  'targets': [
+    {
+      # GN version: //media/capture
+      'target_name': 'capture',
+      'type': '<(component)',
+      'hard_dependency': 1,
+      'dependencies': [
+        '<(DEPTH)/base/base.gyp:base',
+        '<(DEPTH)/base/base.gyp:base_i18n',
+        '<(DEPTH)/media/media.gyp:media',
+        '<(DEPTH)/media/media.gyp:shared_memory_support',  # For audio support.
+        '<(DEPTH)/skia/skia.gyp:skia',
+        '<(DEPTH)/ui/gfx/gfx.gyp:gfx',
+        '<(DEPTH)/ui/gfx/gfx.gyp:gfx_geometry',
+      ],
+      'defines': [
+        'CAPTURE_IMPLEMENTATION',
+      ],
+      'include_dirs': [
+        '<(DEPTH)/',
+      ],
+      'sources': [
+        '<@(capture_sources)'
+      ],
+      'conditions': [
+        ['OS=="android"', {
+          'dependencies': [
+            'capture_java',
+          ],
+        }],
+        ['OS=="mac"', {
+          'dependencies': [
+            '<(DEPTH)/third_party/decklink/decklink.gyp:decklink',
+          ],
+        }],
+        ['chromeos==1', {
+          'dependencies': [
+            '<(DEPTH)/ui/display/display.gyp:display',
+          ],
+        }],
+        ['OS=="linux" and use_udev==1', {
+          'dependencies': [
+            '<(DEPTH)/device/udev_linux/udev.gyp:udev_linux',
+          ],
+        }],
+        ['OS=="win"', {
+          'dependencies': [
+            '<(DEPTH)/media/media.gyp:mf_initializer',
+          ],
+          # TODO(jschuh): http://crbug.com/167187 fix size_t to int truncations.
+          'msvs_disabled_warnings': [ 4267, ],
+        }],
+      ],
+    },
+
+    {
+      # GN version: //media/capture:unittests source_set
+      'target_name': 'unittests',
+      'type': 'none',
+      'dependencies': [
+        'capture',
+      ],
+      'direct_dependent_settings': {
+        'sources': [
+          '<@(capture_unittests_sources)'
+        ],
+      },
+    },
+  ],
+
+  'conditions': [
+    ['OS=="android"', {
+      'targets': [
+        {
+          'target_name': 'capture_java',
+          'type': 'none',
+          'dependencies': [
+            '/base/base.gyp:base',
+            'media_android_captureapitype',
+            'media_android_imageformat',
+            'video_capture_android_jni_headers',
+          ],
+          'export_dependent_settings': [
+            '../base/base.gyp:base',
+          ],
+          'variables': {
+            'java_in_dir': 'video/android/java',
+          },
+          'includes': ['../../build/java.gypi'],
+        },
+        {
+          'target_name': 'media_android_captureapitype',
+          'type': 'none',
+          'variables': {
+            'source_file': 'video/video_capture_device.h',
+          },
+         'includes': [ '../../build/android/java_cpp_enum.gypi' ],
+        },
+        {
+          'target_name': 'media_android_imageformat',
+          'type': 'none',
+          'variables': {
+            'source_file': 'video/android/video_capture_device_android.h',
+          },
+          'includes': [ '../../build/android/java_cpp_enum.gypi' ],
+        },
+        {
+          'target_name': 'video_capture_android_jni_headers',
+          'type': 'none',
+          'sources': [
+            'video/android/java/src/org/chromium/media/VideoCapture.java',
+            'video/android/java/src/org/chromium/media/VideoCaptureFactory.java',
+          ],
+          'variables': {
+           'jni_gen_package': 'media',
+          },
+         'includes': ['../../build/jni_generator.gypi'],
+        },
+      ],
+    }],
+  ],
+}
diff --git a/media/capture/capture.gypi b/media/capture/capture.gypi
deleted file mode 100644
index 2535c44..0000000
--- a/media/capture/capture.gypi
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'defines': [
-    'MEDIA_IMPLEMENTATION',
-  ],
-  'variables': {
-    # GN version: //media/capture:capture
-    'capture_sources': [
-      'capture/content/animated_content_sampler.cc',
-      'capture/content/animated_content_sampler.h',
-      'capture/content/capture_resolution_chooser.cc',
-      'capture/content/capture_resolution_chooser.h',
-      'capture/content/feedback_signal_accumulator.h',
-      'capture/content/screen_capture_device_core.cc',
-      'capture/content/screen_capture_device_core.h',
-      'capture/content/smooth_event_sampler.cc',
-      'capture/content/smooth_event_sampler.h',
-      'capture/content/thread_safe_capture_oracle.cc',
-      'capture/content/thread_safe_capture_oracle.h',
-      'capture/content/video_capture_oracle.cc',
-      'capture/content/video_capture_oracle.h',
-      'capture/device_monitor_mac.h',
-      'capture/device_monitor_mac.mm',
-      'capture/system_message_window_win.cc',
-      'capture/system_message_window_win.h',
-      'capture/video/android/video_capture_device_android.cc',
-      'capture/video/android/video_capture_device_android.h',
-      'capture/video/android/video_capture_device_factory_android.cc',
-      'capture/video/android/video_capture_device_factory_android.h',
-      'capture/video/fake_video_capture_device.cc',
-      'capture/video/fake_video_capture_device.h',
-      'capture/video/fake_video_capture_device_factory.cc',
-      'capture/video/fake_video_capture_device_factory.h',
-      'capture/video/file_video_capture_device.cc',
-      'capture/video/file_video_capture_device.h',
-      'capture/video/file_video_capture_device_factory.cc',
-      'capture/video/file_video_capture_device_factory.h',
-      'capture/video/linux/v4l2_capture_delegate.cc',
-      'capture/video/linux/v4l2_capture_delegate.h',
-      'capture/video/linux/video_capture_device_chromeos.cc',
-      'capture/video/linux/video_capture_device_chromeos.h',
-      'capture/video/linux/video_capture_device_factory_linux.cc',
-      'capture/video/linux/video_capture_device_factory_linux.h',
-      'capture/video/linux/video_capture_device_linux.cc',
-      'capture/video/linux/video_capture_device_linux.h',
-      'capture/video/mac/video_capture_device_avfoundation_mac.h',
-      'capture/video/mac/video_capture_device_avfoundation_mac.mm',
-      'capture/video/mac/video_capture_device_decklink_mac.h',
-      'capture/video/mac/video_capture_device_decklink_mac.mm',
-      'capture/video/mac/video_capture_device_factory_mac.h',
-      'capture/video/mac/video_capture_device_factory_mac.mm',
-      'capture/video/mac/video_capture_device_mac.h',
-      'capture/video/mac/video_capture_device_mac.mm',
-      'capture/video/scoped_result_callback.h',
-      'capture/video/video_capture_device.cc',
-      'capture/video/video_capture_device.h',
-      'capture/video/video_capture_device_factory.cc',
-      'capture/video/video_capture_device_factory.h',
-      'capture/video/video_capture_device_info.cc',
-      'capture/video/video_capture_device_info.h',
-      'capture/video/win/capability_list_win.cc',
-      'capture/video/win/capability_list_win.h',
-      'capture/video/win/filter_base_win.cc',
-      'capture/video/win/filter_base_win.h',
-      'capture/video/win/pin_base_win.cc',
-      'capture/video/win/pin_base_win.h',
-      'capture/video/win/sink_filter_observer_win.h',
-      'capture/video/win/sink_filter_win.cc',
-      'capture/video/win/sink_filter_win.h',
-      'capture/video/win/sink_input_pin_win.cc',
-      'capture/video/win/sink_input_pin_win.h',
-      'capture/video/win/video_capture_device_factory_win.cc',
-      'capture/video/win/video_capture_device_factory_win.h',
-      'capture/video/win/video_capture_device_mf_win.cc',
-      'capture/video/win/video_capture_device_mf_win.h',
-      'capture/video/win/video_capture_device_win.cc',
-      'capture/video/win/video_capture_device_win.h'
-    ],
-
-    # GN version: //media/capture:unittests
-    'capture_unittests_sources': [
-      'capture/content/animated_content_sampler_unittest.cc',
-      'capture/content/capture_resolution_chooser_unittest.cc',
-      'capture/content/feedback_signal_accumulator_unittest.cc',
-      'capture/content/smooth_event_sampler_unittest.cc',
-      'capture/content/video_capture_oracle_unittest.cc',
-      'capture/system_message_window_win_unittest.cc',
-      'capture/video/fake_video_capture_device_unittest.cc',
-      'capture/video/mac/video_capture_device_factory_mac_unittest.mm',
-      'capture/video/video_capture_device_unittest.cc'
-    ],
-
-    # The following files lack appropriate platform suffixes.
-    'conditions': [
-      ['OS=="linux" and use_udev==1', {
-        'capture_sources': [
-          'capture/device_monitor_udev.cc',
-          'capture/device_monitor_udev.h',
-        ],
-      }],
-    ],
-  },
-}
diff --git a/media/capture/capture_export.h b/media/capture/capture_export.h
new file mode 100644
index 0000000..93c6511f
--- /dev/null
+++ b/media/capture/capture_export.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_CAPTURE_CAPTURE_EXPORT_H_
+#define MEDIA_CAPTURE_CAPTURE_EXPORT_H_
+
+#if defined(COMPONENT_BUILD)
+#if defined(WIN32)
+
+#if defined(CAPTURE_IMPLEMENTATION)
+#define CAPTURE_EXPORT __declspec(dllexport)
+#else
+#define CAPTURE_EXPORT __declspec(dllimport)
+#endif  // defined(CAPTURE_IMPLEMENTATION)
+
+#else  // defined(WIN32)
+#if defined(CAPTURE_IMPLEMENTATION)
+#define CAPTURE_EXPORT __attribute__((visibility("default")))
+#else
+#define CAPTURE_EXPORT
+#endif
+#endif
+
+#else  // defined(COMPONENT_BUILD)
+#define CAPTURE_EXPORT
+#endif
+
+#endif  // MEDIA_CAPTURE_CAPTURE_EXPORT_H_
diff --git a/media/capture/content/animated_content_sampler.h b/media/capture/content/animated_content_sampler.h
index f8cb6f5..0539de7 100644
--- a/media/capture/content/animated_content_sampler.h
+++ b/media/capture/content/animated_content_sampler.h
@@ -8,7 +8,7 @@
 #include <deque>
 
 #include "base/time/time.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace media {
@@ -22,7 +22,7 @@
 // In addition, AnimatedContentSampler will provide rewritten frame timestamps,
 // for downstream consumers, that are "truer" to the source content than to the
 // local presentation hardware.
-class MEDIA_EXPORT AnimatedContentSampler {
+class CAPTURE_EXPORT AnimatedContentSampler {
  public:
   explicit AnimatedContentSampler(base::TimeDelta min_capture_period);
   ~AnimatedContentSampler();
diff --git a/media/capture/content/capture_resolution_chooser.h b/media/capture/content/capture_resolution_chooser.h
index e995e93..cbc887d 100644
--- a/media/capture/content/capture_resolution_chooser.h
+++ b/media/capture/content/capture_resolution_chooser.h
@@ -7,8 +7,8 @@
 
 #include <vector>
 
-#include "media/base/media_export.h"
 #include "media/base/video_capture_types.h"
+#include "media/capture/capture_export.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace media {
@@ -31,7 +31,7 @@
 // possibile snapped frame sizes are computed relative to the resolution of the
 // source content: They are the same or smaller in size, and are of the same
 // aspect ratio.
-class MEDIA_EXPORT CaptureResolutionChooser {
+class CAPTURE_EXPORT CaptureResolutionChooser {
  public:
   // media::ResolutionChangePolicy determines whether the variable frame
   // resolutions being computed must adhere to a fixed aspect ratio or not, or
diff --git a/media/capture/content/feedback_signal_accumulator.h b/media/capture/content/feedback_signal_accumulator.h
index d27887a3..33873f1 100644
--- a/media/capture/content/feedback_signal_accumulator.h
+++ b/media/capture/content/feedback_signal_accumulator.h
@@ -6,7 +6,7 @@
 #define MEDIA_CAPTURE_CONTENT_FEEDBACK_SIGNAL_ACCUMULATOR_H_
 
 #include "base/time/time.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 
 namespace media {
 
diff --git a/media/capture/content/screen_capture_device_core.h b/media/capture/content/screen_capture_device_core.h
index 6d1c8b86..3f8884b 100644
--- a/media/capture/content/screen_capture_device_core.h
+++ b/media/capture/content/screen_capture_device_core.h
@@ -11,7 +11,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 #include "media/capture/content/thread_safe_capture_oracle.h"
 #include "media/capture/video/video_capture_device.h"
 
@@ -26,7 +26,7 @@
 class ThreadSafeCaptureOracle;
 
 // Keeps track of the video capture source frames and executes copying.
-class MEDIA_EXPORT VideoCaptureMachine {
+class CAPTURE_EXPORT VideoCaptureMachine {
  public:
   VideoCaptureMachine();
   virtual ~VideoCaptureMachine();
@@ -72,7 +72,7 @@
 // (see notes at top of this file).  It times the start of successive captures
 // and facilitates the processing of each through the stages of the
 // pipeline.
-class MEDIA_EXPORT ScreenCaptureDeviceCore
+class CAPTURE_EXPORT ScreenCaptureDeviceCore
     : public base::SupportsWeakPtr<ScreenCaptureDeviceCore> {
  public:
   ScreenCaptureDeviceCore(std::unique_ptr<VideoCaptureMachine> capture_machine);
diff --git a/media/capture/content/smooth_event_sampler.h b/media/capture/content/smooth_event_sampler.h
index 66c39e0..47ed58e 100644
--- a/media/capture/content/smooth_event_sampler.h
+++ b/media/capture/content/smooth_event_sampler.h
@@ -7,12 +7,12 @@
 
 #include "base/macros.h"
 #include "base/time/time.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 
 namespace media {
 
 // Filters a sequence of events to achieve a target frequency.
-class MEDIA_EXPORT SmoothEventSampler {
+class CAPTURE_EXPORT SmoothEventSampler {
  public:
   explicit SmoothEventSampler(base::TimeDelta min_capture_period);
 
diff --git a/media/capture/content/thread_safe_capture_oracle.h b/media/capture/content/thread_safe_capture_oracle.h
index c4d4a8d..f54315b 100644
--- a/media/capture/content/thread_safe_capture_oracle.h
+++ b/media/capture/content/thread_safe_capture_oracle.h
@@ -9,8 +9,8 @@
 #include <string>
 
 #include "base/memory/ref_counted.h"
-#include "media/base/media_export.h"
 #include "media/base/video_frame.h"
+#include "media/capture/capture_export.h"
 #include "media/capture/content/video_capture_oracle.h"
 #include "media/capture/video/video_capture_device.h"
 
@@ -27,7 +27,7 @@
 // the VideoCaptureOracle, which decides which frames to capture, and a
 // VideoCaptureDevice::Client, which allocates and receives the captured
 // frames, in a lock to synchronize state between the two.
-class MEDIA_EXPORT ThreadSafeCaptureOracle
+class CAPTURE_EXPORT ThreadSafeCaptureOracle
     : public base::RefCountedThreadSafe<ThreadSafeCaptureOracle> {
  public:
   ThreadSafeCaptureOracle(std::unique_ptr<VideoCaptureDevice::Client> client,
diff --git a/media/capture/content/video_capture_oracle.h b/media/capture/content/video_capture_oracle.h
index 36779b94..3fdb35c 100644
--- a/media/capture/content/video_capture_oracle.h
+++ b/media/capture/content/video_capture_oracle.h
@@ -7,7 +7,7 @@
 
 #include "base/callback_forward.h"
 #include "base/time/time.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 #include "media/capture/content/animated_content_sampler.h"
 #include "media/capture/content/capture_resolution_chooser.h"
 #include "media/capture/content/feedback_signal_accumulator.h"
@@ -20,7 +20,7 @@
 // from a video capture device.  It is informed of every update by the device;
 // this empowers it to look into the future and decide if a particular frame
 // ought to be captured in order to achieve its target frame rate.
-class MEDIA_EXPORT VideoCaptureOracle {
+class CAPTURE_EXPORT VideoCaptureOracle {
  public:
   enum Event {
     kCompositorUpdate,
diff --git a/media/capture/device_monitor_mac.h b/media/capture/device_monitor_mac.h
index c243c56..c6db8b9 100644
--- a/media/capture/device_monitor_mac.h
+++ b/media/capture/device_monitor_mac.h
@@ -10,7 +10,7 @@
 #include "base/macros.h"
 #include "base/system_monitor/system_monitor.h"
 #include "base/threading/thread_checker.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 
 namespace {
 class DeviceMonitorMacImpl;
@@ -21,7 +21,7 @@
 // Class to track audio/video devices removal or addition via callback to
 // base::SystemMonitor ProcessDevicesChanged(). A single object of this class
 // is created from the browser main process and lives as long as this one.
-class MEDIA_EXPORT DeviceMonitorMac {
+class CAPTURE_EXPORT DeviceMonitorMac {
  public:
   DeviceMonitorMac();
   ~DeviceMonitorMac();
diff --git a/media/capture/device_monitor_udev.h b/media/capture/device_monitor_udev.h
index 4571072d..a8f9d82 100644
--- a/media/capture/device_monitor_udev.h
+++ b/media/capture/device_monitor_udev.h
@@ -14,7 +14,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
 #include "base/single_thread_task_runner.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 
 extern "C" {
 struct udev_device;
@@ -26,7 +26,7 @@
 
 namespace media {
 
-class MEDIA_EXPORT DeviceMonitorLinux
+class CAPTURE_EXPORT DeviceMonitorLinux
     : public base::MessageLoop::DestructionObserver {
  public:
   explicit DeviceMonitorLinux(
diff --git a/media/capture/system_message_window_win.h b/media/capture/system_message_window_win.h
index 1dde0edb..6468317 100644
--- a/media/capture/system_message_window_win.h
+++ b/media/capture/system_message_window_win.h
@@ -10,11 +10,11 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 
 namespace media {
 
-class MEDIA_EXPORT SystemMessageWindowWin {
+class CAPTURE_EXPORT SystemMessageWindowWin {
  public:
   SystemMessageWindowWin();
 
diff --git a/media/capture/video/android/BUILD.gn b/media/capture/video/android/BUILD.gn
index b958038..ca97117 100644
--- a/media/capture/video/android/BUILD.gn
+++ b/media/capture/video/android/BUILD.gn
@@ -14,6 +14,12 @@
   sources = [
     "capture_jni_registrar.cc",
     "capture_jni_registrar.h",
+    "photo_capabilities.cc",
+    "photo_capabilities.h",
+    "video_capture_device_android.cc",
+    "video_capture_device_android.h",
+    "video_capture_device_factory_android.cc",
+    "video_capture_device_factory_android.h",
   ]
   configs += [
     "//media:media_config",
diff --git a/media/capture/video/android/capture_jni_registrar.h b/media/capture/video/android/capture_jni_registrar.h
index df15a10..361c5ab9 100644
--- a/media/capture/video/android/capture_jni_registrar.h
+++ b/media/capture/video/android/capture_jni_registrar.h
@@ -7,12 +7,12 @@
 
 #include <jni.h>
 
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 
 namespace media {
 
 // Register all JNI bindings necessary for capture.
-MEDIA_EXPORT bool RegisterCaptureJni(JNIEnv* env);
+CAPTURE_EXPORT bool RegisterCaptureJni(JNIEnv* env);
 
 }  // namespace media
 
diff --git a/media/capture/video/android/video_capture_device_android.h b/media/capture/video/android/video_capture_device_android.h
index 8eede91..9de33bf 100644
--- a/media/capture/video/android/video_capture_device_android.h
+++ b/media/capture/video/android/video_capture_device_android.h
@@ -13,7 +13,7 @@
 #include "base/synchronization/lock.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 #include "media/capture/video/video_capture_device.h"
 
 namespace tracked_objects {
@@ -26,7 +26,7 @@
 // by VideoCaptureManager on its own thread, while OnFrameAvailable is called
 // on JAVA thread (i.e., UI thread). Both will access |state_| and |client_|,
 // but only VideoCaptureManager would change their value.
-class MEDIA_EXPORT VideoCaptureDeviceAndroid : public VideoCaptureDevice {
+class CAPTURE_EXPORT VideoCaptureDeviceAndroid : public VideoCaptureDevice {
  public:
   // Automatically generated enum to interface with Java world.
   //
diff --git a/media/capture/video/android/video_capture_device_factory_android.h b/media/capture/video/android/video_capture_device_factory_android.h
index f45050ab..aa1f366 100644
--- a/media/capture/video/android/video_capture_device_factory_android.h
+++ b/media/capture/video/android/video_capture_device_factory_android.h
@@ -17,7 +17,7 @@
 
 // VideoCaptureDeviceFactory on Android. This class implements the static
 // VideoCapture methods and the factory of VideoCaptureAndroid.
-class MEDIA_EXPORT VideoCaptureDeviceFactoryAndroid
+class CAPTURE_EXPORT VideoCaptureDeviceFactoryAndroid
     : public VideoCaptureDeviceFactory {
  public:
   static bool RegisterVideoCaptureDeviceFactory(JNIEnv* env);
diff --git a/media/capture/video/fake_video_capture_device.h b/media/capture/video/fake_video_capture_device.h
index cb29b789..a3334a78 100644
--- a/media/capture/video/fake_video_capture_device.h
+++ b/media/capture/video/fake_video_capture_device.h
@@ -22,7 +22,7 @@
 
 namespace media {
 
-class MEDIA_EXPORT FakeVideoCaptureDevice : public VideoCaptureDevice {
+class CAPTURE_EXPORT FakeVideoCaptureDevice : public VideoCaptureDevice {
  public:
   enum class BufferOwnership {
     OWN_BUFFERS,
diff --git a/media/capture/video/fake_video_capture_device_factory.h b/media/capture/video/fake_video_capture_device_factory.h
index 2876bf1..6f67c811 100644
--- a/media/capture/video/fake_video_capture_device_factory.h
+++ b/media/capture/video/fake_video_capture_device_factory.h
@@ -14,7 +14,7 @@
 
 // Extension of VideoCaptureDeviceFactory to create and manipulate fake devices,
 // not including file-based ones.
-class MEDIA_EXPORT FakeVideoCaptureDeviceFactory
+class CAPTURE_EXPORT FakeVideoCaptureDeviceFactory
     : public VideoCaptureDeviceFactory {
  public:
   FakeVideoCaptureDeviceFactory();
diff --git a/media/capture/video/file_video_capture_device.h b/media/capture/video/file_video_capture_device.h
index c3ecbfc..53d2670 100644
--- a/media/capture/video/file_video_capture_device.h
+++ b/media/capture/video/file_video_capture_device.h
@@ -32,7 +32,7 @@
 // Example MJPEG videos can be found in media/data/test/bear.mjpeg.
 // Restrictions: Y4M videos should have .y4m file extension and MJPEG videos
 // should have .mjpeg file extension.
-class MEDIA_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice {
+class CAPTURE_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice {
  public:
   // Reads and parses the header of a |file_path|, returning the collected
   // pixel format in |video_format|. Returns true on file parsed successfully,
diff --git a/media/capture/video/file_video_capture_device_factory.h b/media/capture/video/file_video_capture_device_factory.h
index 42ae083..8d99a28 100644
--- a/media/capture/video/file_video_capture_device_factory.h
+++ b/media/capture/video/file_video_capture_device_factory.h
@@ -12,7 +12,7 @@
 // Extension of VideoCaptureDeviceFactory to create and manipulate file-backed
 // fake devices. These devices play back video-only files as video capture
 // input.
-class MEDIA_EXPORT FileVideoCaptureDeviceFactory
+class CAPTURE_EXPORT FileVideoCaptureDeviceFactory
     : public VideoCaptureDeviceFactory {
  public:
   FileVideoCaptureDeviceFactory() {}
diff --git a/media/capture/video/linux/video_capture_device_factory_linux.h b/media/capture/video/linux/video_capture_device_factory_linux.h
index 02ebdfd..2790520 100644
--- a/media/capture/video/linux/video_capture_device_factory_linux.h
+++ b/media/capture/video/linux/video_capture_device_factory_linux.h
@@ -16,7 +16,7 @@
 
 // Extension of VideoCaptureDeviceFactory to create and manipulate Linux
 // devices.
-class MEDIA_EXPORT VideoCaptureDeviceFactoryLinux
+class CAPTURE_EXPORT VideoCaptureDeviceFactoryLinux
     : public VideoCaptureDeviceFactory {
  public:
   explicit VideoCaptureDeviceFactoryLinux(
diff --git a/media/capture/video/mac/video_capture_device_decklink_mac.h b/media/capture/video/mac/video_capture_device_decklink_mac.h
index 136872d..b078f21 100644
--- a/media/capture/video/mac/video_capture_device_decklink_mac.h
+++ b/media/capture/video/mac/video_capture_device_decklink_mac.h
@@ -32,7 +32,7 @@
 // Creates a reference counted |decklink_capture_delegate_| that does all the
 // DeckLink SDK configuration and capture work while holding a weak reference to
 // us for sending back frames, logs and error messages.
-class MEDIA_EXPORT VideoCaptureDeviceDeckLinkMac : public VideoCaptureDevice {
+class CAPTURE_EXPORT VideoCaptureDeviceDeckLinkMac : public VideoCaptureDevice {
  public:
   // Gets the names of all DeckLink video capture devices connected to this
   // computer, as enumerated by the DeckLink SDK. To allow the user to choose
diff --git a/media/capture/video/mac/video_capture_device_factory_mac.h b/media/capture/video/mac/video_capture_device_factory_mac.h
index 891284b..3c57efe 100644
--- a/media/capture/video/mac/video_capture_device_factory_mac.h
+++ b/media/capture/video/mac/video_capture_device_factory_mac.h
@@ -13,7 +13,7 @@
 namespace media {
 
 // Extension of VideoCaptureDeviceFactory to create and manipulate Mac devices.
-class MEDIA_EXPORT VideoCaptureDeviceFactoryMac
+class CAPTURE_EXPORT VideoCaptureDeviceFactoryMac
     : public VideoCaptureDeviceFactory {
  public:
   VideoCaptureDeviceFactoryMac();
diff --git a/media/capture/video/mac/video_capture_device_mac.h b/media/capture/video/mac/video_capture_device_mac.h
index 5b7a090..88b986b 100644
--- a/media/capture/video/mac/video_capture_device_mac.h
+++ b/media/capture/video/mac/video_capture_device_mac.h
@@ -33,7 +33,7 @@
 }  // namespace tracked_objects
 
 // Small class to bundle device name and connection type into a dictionary.
-MEDIA_EXPORT
+CAPTURE_EXPORT
 @interface DeviceNameAndTransportType : NSObject {
  @private
   base::scoped_nsobject<NSString> deviceName_;
diff --git a/media/capture/video/video_capture_device.h b/media/capture/video/video_capture_device.h
index ece44329..ffdb0b1 100644
--- a/media/capture/video/video_capture_device.h
+++ b/media/capture/video/video_capture_device.h
@@ -26,9 +26,9 @@
 #include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "media/base/media_export.h"
 #include "media/base/video_capture_types.h"
 #include "media/base/video_frame.h"
+#include "media/capture/capture_export.h"
 #include "media/capture/video/scoped_result_callback.h"
 #include "mojo/public/cpp/bindings/array.h"
 #include "ui/gfx/gpu_memory_buffer.h"
@@ -39,7 +39,7 @@
 
 namespace media {
 
-class MEDIA_EXPORT VideoCaptureDevice {
+class CAPTURE_EXPORT VideoCaptureDevice {
  public:
   // Represents a capture device name and ID.
   // You should not create an instance of this class directly by e.g. setting
@@ -49,7 +49,7 @@
   // The reason for this is that a device name might contain platform specific
   // settings that are relevant only to the platform specific implementation of
   // VideoCaptureDevice::Create.
-  class MEDIA_EXPORT Name {
+  class CAPTURE_EXPORT Name {
    public:
     Name();
     Name(const std::string& name, const std::string& id);
@@ -179,10 +179,10 @@
   // is actually two-in-one: clients may implement OnIncomingCapturedData() or
   // ReserveOutputBuffer() + OnIncomingCapturedVideoFrame(), or all of them.
   // All clients must implement OnError().
-  class MEDIA_EXPORT Client {
+  class CAPTURE_EXPORT Client {
    public:
     // Memory buffer returned by Client::ReserveOutputBuffer().
-    class MEDIA_EXPORT Buffer {
+    class CAPTURE_EXPORT Buffer {
      public:
       virtual ~Buffer() = 0;
       virtual int id() const = 0;
diff --git a/media/capture/video/video_capture_device_factory.h b/media/capture/video/video_capture_device_factory.h
index fd85ed85..de16133 100644
--- a/media/capture/video/video_capture_device_factory.h
+++ b/media/capture/video/video_capture_device_factory.h
@@ -15,7 +15,7 @@
 // devices in the different platforms. VCDFs are created by MediaStreamManager
 // on IO thread and plugged into VideoCaptureManager, who owns and operates them
 // in Device Thread (a.k.a. Audio Thread).
-class MEDIA_EXPORT VideoCaptureDeviceFactory {
+class CAPTURE_EXPORT VideoCaptureDeviceFactory {
  public:
   static std::unique_ptr<VideoCaptureDeviceFactory> CreateFactory(
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
diff --git a/media/capture/video/video_capture_device_info.h b/media/capture/video/video_capture_device_info.h
index e091dec..5f68649b0 100644
--- a/media/capture/video/video_capture_device_info.h
+++ b/media/capture/video/video_capture_device_info.h
@@ -11,7 +11,7 @@
 namespace media {
 
 // A convenience wrap of a device's name and associated supported formats.
-struct MEDIA_EXPORT VideoCaptureDeviceInfo {
+struct CAPTURE_EXPORT VideoCaptureDeviceInfo {
   VideoCaptureDeviceInfo();
   VideoCaptureDeviceInfo(const VideoCaptureDevice::Name& name,
                          const VideoCaptureFormats& supported_formats);
diff --git a/media/capture/video/win/video_capture_device_factory_win.h b/media/capture/video/win/video_capture_device_factory_win.h
index 09b5768..86477a30 100644
--- a/media/capture/video/win/video_capture_device_factory_win.h
+++ b/media/capture/video/win/video_capture_device_factory_win.h
@@ -14,7 +14,7 @@
 
 // Extension of VideoCaptureDeviceFactory to create and manipulate Windows
 // devices, via either DirectShow or MediaFoundation APIs.
-class MEDIA_EXPORT VideoCaptureDeviceFactoryWin
+class CAPTURE_EXPORT VideoCaptureDeviceFactoryWin
     : public VideoCaptureDeviceFactory {
  public:
   static bool PlatformSupportsMediaFoundation();
diff --git a/media/capture/video/win/video_capture_device_mf_win.h b/media/capture/video/win/video_capture_device_mf_win.h
index ae6d5ca9..971b537 100644
--- a/media/capture/video/win/video_capture_device_mf_win.h
+++ b/media/capture/video/win/video_capture_device_mf_win.h
@@ -19,7 +19,7 @@
 #include "base/synchronization/lock.h"
 #include "base/threading/non_thread_safe.h"
 #include "base/win/scoped_comptr.h"
-#include "media/base/media_export.h"
+#include "media/capture/capture_export.h"
 #include "media/capture/video/video_capture_device.h"
 
 interface IMFSourceReader;
@@ -35,8 +35,8 @@
 const DWORD kFirstVideoStream =
     static_cast<DWORD>(MF_SOURCE_READER_FIRST_VIDEO_STREAM);
 
-class MEDIA_EXPORT VideoCaptureDeviceMFWin : public base::NonThreadSafe,
-                                             public VideoCaptureDevice {
+class CAPTURE_EXPORT VideoCaptureDeviceMFWin : public base::NonThreadSafe,
+                                               public VideoCaptureDevice {
  public:
   static bool FormatFromGuid(const GUID& guid, VideoPixelFormat* format);
 
diff --git a/media/cast/cast.gyp b/media/cast/cast.gyp
index b2d930a..4d8e83e 100644
--- a/media/cast/cast.gyp
+++ b/media/cast/cast.gyp
@@ -131,6 +131,9 @@
             '<(DEPTH)/third_party/libvpx/libvpx.gyp:libvpx',
           ],
         }], # OS=="ios"
+        ['OS=="win"', {
+          'dependencies': [ '<(DEPTH)/media/media.gyp:mf_initializer' ],
+        }],
       ], # conditions
     },
     {
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index 2f31c10..2a630e8 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -331,9 +331,11 @@
       "dxva_video_decode_accelerator_win.h",
     ]
     configs += [
+      # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
       "//build/config/compiler:no_size_t_to_int_warning",
       "//third_party/khronos:khronos_headers",
     ]
+    public_deps += [ "//media/base/win" ]
     deps += [ "//third_party/angle:includes" ]
     libs += [
       "d3d9.lib",
diff --git a/media/gpu/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2_slice_video_decode_accelerator.cc
index d56e655..3e26ead6 100644
--- a/media/gpu/v4l2_slice_video_decode_accelerator.cc
+++ b/media/gpu/v4l2_slice_video_decode_accelerator.cc
@@ -31,20 +31,22 @@
 #include "ui/gl/scoped_binders.h"
 
 #define LOGF(level) LOG(level) << __FUNCTION__ << "(): "
+#define DLOGF(level) DLOG(level) << __FUNCTION__ << "(): "
 #define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): "
+#define PLOGF(level) PLOG(level) << __FUNCTION__ << "(): "
 
-#define NOTIFY_ERROR(x)                        \
-  do {                                         \
-    LOG(ERROR) << "Setting error state:" << x; \
-    SetErrorState(x);                          \
+#define NOTIFY_ERROR(x)                         \
+  do {                                          \
+    LOGF(ERROR) << "Setting error state:" << x; \
+    SetErrorState(x);                           \
   } while (0)
 
-#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str)          \
-  do {                                                                   \
-    if (device_->Ioctl(type, arg) != 0) {                                \
-      PLOG(ERROR) << __FUNCTION__ << "(): ioctl() failed: " << type_str; \
-      return value;                                                      \
-    }                                                                    \
+#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
+  do {                                                          \
+    if (device_->Ioctl(type, arg) != 0) {                       \
+      PLOGF(ERROR) << "ioctl() failed: " << type_str;           \
+      return value;                                             \
+    }                                                           \
   } while (0)
 
 #define IOCTL_OR_ERROR_RETURN(type, arg) \
@@ -53,10 +55,10 @@
 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
   IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
 
-#define IOCTL_OR_LOG_ERROR(type, arg)                                 \
-  do {                                                                \
-    if (device_->Ioctl(type, arg) != 0)                               \
-      PLOG(ERROR) << __FUNCTION__ << "(): ioctl() failed: " << #type; \
+#define IOCTL_OR_LOG_ERROR(type, arg)              \
+  do {                                             \
+    if (device_->Ioctl(type, arg) != 0)            \
+      PLOGF(ERROR) << "ioctl() failed: " << #type; \
   } while (0)
 
 namespace media {
@@ -487,23 +489,23 @@
   output_planes_count_ = 1;
 
   if (egl_display_ == EGL_NO_DISPLAY) {
-    LOG(ERROR) << "Initialize(): could not get EGLDisplay";
+    LOGF(ERROR) << "could not get EGLDisplay";
     return false;
   }
 
   // We need the context to be initialized to query extensions.
   if (!make_context_current_cb_.is_null()) {
     if (!make_context_current_cb_.Run()) {
-      LOG(ERROR) << "Initialize(): could not make context current";
+      LOGF(ERROR) << "could not make context current";
       return false;
     }
 
     if (!gl::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
-      LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
+      LOGF(ERROR) << "context does not have EGL_KHR_fence_sync";
       return false;
     }
   } else {
-    DVLOG(1) << "No GL callbacks provided, initializing without GL support";
+    DVLOGF(1) << "No GL callbacks provided, initializing without GL support";
   }
 
   // Capabilities check.
@@ -511,8 +513,8 @@
   const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
-    LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
-               << ", caps check failed: 0x" << std::hex << caps.capabilities;
+    LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP"
+                << ", caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
@@ -520,7 +522,7 @@
     return false;
 
   if (!decoder_thread_.Start()) {
-    DLOG(ERROR) << "Initialize(): device thread failed to start";
+    DLOGF(ERROR) << "device thread failed to start";
     return false;
   }
   decoder_thread_task_runner_ = decoder_thread_.task_runner();
@@ -622,8 +624,8 @@
   }
 
   if (!is_format_supported) {
-    DVLOG(1) << "Input fourcc " << input_format_fourcc
-             << " not supported by device.";
+    DVLOGF(1) << "Input fourcc " << input_format_fourcc
+              << " not supported by device.";
     return false;
   }
 
@@ -650,7 +652,7 @@
   }
 
   if (output_format_fourcc_ == 0) {
-    LOG(ERROR) << "Could not find a usable output format";
+    LOGF(ERROR) << "Could not find a usable output format";
     return false;
   }
 
@@ -678,7 +680,7 @@
   reqbufs.memory = V4L2_MEMORY_MMAP;
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_REQBUFS, &reqbufs);
   if (reqbufs.count < kNumInputBuffers) {
-    PLOG(ERROR) << "Could not allocate enough output buffers";
+    PLOGF(ERROR) << "Could not allocate enough output buffers";
     return false;
   }
   input_buffer_map_.resize(reqbufs.count);
@@ -702,7 +704,7 @@
                                   MAP_SHARED,
                                   buffer.m.planes[0].m.mem_offset);
     if (address == MAP_FAILED) {
-      PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
+      PLOGF(ERROR) << "mmap() failed";
       return false;
     }
     input_buffer_map_[i].address = address;
@@ -735,7 +737,7 @@
   format.fmt.pix_mp.num_planes = input_planes_count_;
 
   if (device_->Ioctl(VIDIOC_S_FMT, &format) != 0) {
-    PLOG(ERROR) << "Failed setting format to: " << output_format_fourcc_;
+    PLOGF(ERROR) << "Failed setting format to: " << output_format_fourcc_;
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -746,7 +748,8 @@
   DCHECK_EQ(coded_size_.height() % 16, 0);
 
   if (!gfx::Rect(coded_size_).Contains(gfx::Rect(visible_size_))) {
-    LOG(ERROR) << "Got invalid adjusted coded size: " << coded_size_.ToString();
+    LOGF(ERROR) << "Got invalid adjusted coded size: "
+                << coded_size_.ToString();
     return false;
   }
 
@@ -925,7 +928,7 @@
         // EAGAIN if we're just out of buffers to dequeue.
         break;
       }
-      PLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
+      PLOGF(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -953,7 +956,7 @@
         // EAGAIN if we're just out of buffers to dequeue.
         break;
       }
-      PLOG(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
+      PLOGF(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -967,7 +970,7 @@
     V4L2DecodeSurfaceByOutputId::iterator it =
         surfaces_at_device_.find(dqbuf.index);
     if (it == surfaces_at_device_.end()) {
-      DLOG(ERROR) << "Got invalid surface from device.";
+      DLOGF(ERROR) << "Got invalid surface from device.";
       NOTIFY_ERROR(PLATFORM_FAILURE);
     }
 
@@ -1149,7 +1152,7 @@
 
   // Start up the device poll thread and schedule its first DevicePollTask().
   if (!device_poll_thread_.Start()) {
-    DLOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
+    DLOGF(ERROR) << "Device thread failed to start";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1179,7 +1182,7 @@
 
   // Signal the DevicePollTask() to stop, and stop the device poll thread.
   if (!device_->SetDevicePollInterrupt()) {
-    PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
+    PLOGF(ERROR) << "SetDevicePollInterrupt(): failed";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1246,7 +1249,7 @@
   DCHECK(decode_task_runner_->BelongsToCurrentThread());
 
   if (bitstream_buffer.id() < 0) {
-    LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+    LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
     if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
       base::SharedMemory::CloseHandle(bitstream_buffer.handle());
     NOTIFY_ERROR(INVALID_ARGUMENT);
@@ -1407,7 +1410,7 @@
   }
 
   surface_set_change_pending_ = false;
-  DVLOG(3) << "Surface set change finished";
+  DVLOGF(3) << "Surface set change finished";
   return true;
 }
 
@@ -1531,7 +1534,7 @@
   IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs);
 
   if (reqbufs.count != buffers.size()) {
-    DLOG(ERROR) << "Could not allocate enough output buffers";
+    DLOGF(ERROR) << "Could not allocate enough output buffers";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -1597,14 +1600,14 @@
   DCHECK(child_task_runner_->BelongsToCurrentThread());
 
   if (get_gl_context_cb_.is_null() || make_context_current_cb_.is_null()) {
-    DLOG(ERROR) << "GL callbacks required for binding to EGLImages";
+    DLOGF(ERROR) << "GL callbacks required for binding to EGLImages";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
 
   gl::GLContext* gl_context = get_gl_context_cb_.Run();
   if (!gl_context || !make_context_current_cb_.Run()) {
-    DLOG(ERROR) << "No GL context";
+    DLOGF(ERROR) << "No GL context";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -2030,7 +2033,7 @@
   size_t i = 0;
   for (const auto& pic : dpb) {
     if (i >= arraysize(v4l2_decode_param_.dpb)) {
-      DVLOG(1) << "Invalid DPB size";
+      DVLOGF(1) << "Invalid DPB size";
       break;
     }
 
diff --git a/media/gpu/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2_video_decode_accelerator.cc
index 6e5ee517..68b34538 100644
--- a/media/gpu/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2_video_decode_accelerator.cc
@@ -29,19 +29,24 @@
 #include "ui/gl/gl_context.h"
 #include "ui/gl/scoped_binders.h"
 
-#define NOTIFY_ERROR(x)                        \
-  do {                                         \
-    LOG(ERROR) << "Setting error state:" << x; \
-    SetErrorState(x);                          \
+#define LOGF(level) LOG(level) << __FUNCTION__ << "(): "
+#define DLOGF(level) DLOG(level) << __FUNCTION__ << "(): "
+#define DVLOGF(level) DVLOG(level) << __FUNCTION__ << "(): "
+#define PLOGF(level) PLOG(level) << __FUNCTION__ << "(): "
+
+#define NOTIFY_ERROR(x)                         \
+  do {                                          \
+    LOGF(ERROR) << "Setting error state:" << x; \
+    SetErrorState(x);                           \
   } while (0)
 
-#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str)      \
-  do {                                                               \
-    if (device_->Ioctl(type, arg) != 0) {                            \
-      PLOG(ERROR) << __func__ << "(): ioctl() failed: " << type_str; \
-      NOTIFY_ERROR(PLATFORM_FAILURE);                                \
-      return value;                                                  \
-    }                                                                \
+#define IOCTL_OR_ERROR_RETURN_VALUE(type, arg, value, type_str) \
+  do {                                                          \
+    if (device_->Ioctl(type, arg) != 0) {                       \
+      PLOGF(ERROR) << "ioctl() failed: " << type_str;           \
+      NOTIFY_ERROR(PLATFORM_FAILURE);                           \
+      return value;                                             \
+    }                                                           \
   } while (0)
 
 #define IOCTL_OR_ERROR_RETURN(type, arg) \
@@ -50,10 +55,10 @@
 #define IOCTL_OR_ERROR_RETURN_FALSE(type, arg) \
   IOCTL_OR_ERROR_RETURN_VALUE(type, arg, false, #type)
 
-#define IOCTL_OR_LOG_ERROR(type, arg)                             \
-  do {                                                            \
-    if (device_->Ioctl(type, arg) != 0)                           \
-      PLOG(ERROR) << __func__ << "(): ioctl() failed: " << #type; \
+#define IOCTL_OR_LOG_ERROR(type, arg)              \
+  do {                                             \
+    if (device_->Ioctl(type, arg) != 0)            \
+      PLOGF(ERROR) << "ioctl() failed: " << #type; \
   } while (0)
 
 namespace media {
@@ -194,14 +199,14 @@
 
 bool V4L2VideoDecodeAccelerator::Initialize(const Config& config,
                                             Client* client) {
-  DVLOG(3) << "Initialize()";
+  DVLOGF(3) << "profile: " << config.profile;
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   DCHECK_EQ(decoder_state_, kUninitialized);
 
   if (!device_->SupportsDecodeProfileForV4L2PixelFormats(
           config.profile, arraysize(supported_input_fourccs_),
           supported_input_fourccs_)) {
-    DVLOG(1) << "Initialize(): unsupported profile=" << config.profile;
+    DVLOGF(1) << "unsupported profile=" << config.profile;
     return false;
   }
 
@@ -234,20 +239,20 @@
   video_profile_ = config.profile;
 
   if (egl_display_ == EGL_NO_DISPLAY) {
-    LOG(ERROR) << "Initialize(): could not get EGLDisplay";
+    LOGF(ERROR) << "could not get EGLDisplay";
     return false;
   }
 
   // We need the context to be initialized to query extensions.
   if (!make_context_current_cb_.Run()) {
-    LOG(ERROR) << "Initialize(): could not make context current";
+    LOGF(ERROR) << "could not make context current";
     return false;
   }
 
 // TODO(posciak): crbug.com/450898.
 #if defined(ARCH_CPU_ARMEL)
   if (!gl::g_driver_egl.ext.b_EGL_KHR_fence_sync) {
-    LOG(ERROR) << "Initialize(): context does not have EGL_KHR_fence_sync";
+    LOGF(ERROR) << "context does not have EGL_KHR_fence_sync";
     return false;
   }
 #endif
@@ -257,8 +262,8 @@
   const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
   IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
   if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
-    LOG(ERROR) << "Initialize(): ioctl() failed: VIDIOC_QUERYCAP"
-               << ", caps check failed: 0x" << std::hex << caps.capabilities;
+    LOGF(ERROR) << "ioctl() failed: VIDIOC_QUERYCAP"
+                << ", caps check failed: 0x" << std::hex << caps.capabilities;
     return false;
   }
 
@@ -279,7 +284,7 @@
     return false;
 
   if (!decoder_thread_.Start()) {
-    LOG(ERROR) << "Initialize(): decoder thread failed to start";
+    LOGF(ERROR) << "decoder thread failed to start";
     return false;
   }
 
@@ -296,12 +301,12 @@
 
 void V4L2VideoDecodeAccelerator::Decode(
     const BitstreamBuffer& bitstream_buffer) {
-  DVLOG(1) << "Decode(): input_id=" << bitstream_buffer.id()
-           << ", size=" << bitstream_buffer.size();
+  DVLOGF(1) << "input_id=" << bitstream_buffer.id()
+            << ", size=" << bitstream_buffer.size();
   DCHECK(decode_task_runner_->BelongsToCurrentThread());
 
   if (bitstream_buffer.id() < 0) {
-    LOG(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
+    LOGF(ERROR) << "Invalid bitstream_buffer, id: " << bitstream_buffer.id();
     if (base::SharedMemory::IsHandleValid(bitstream_buffer.handle()))
       base::SharedMemory::CloseHandle(bitstream_buffer.handle());
     NOTIFY_ERROR(INVALID_ARGUMENT);
@@ -316,23 +321,22 @@
 
 void V4L2VideoDecodeAccelerator::AssignPictureBuffers(
     const std::vector<PictureBuffer>& buffers) {
-  DVLOG(3) << "AssignPictureBuffers(): buffer_count=" << buffers.size();
+  DVLOGF(3) << "buffer_count=" << buffers.size();
   DCHECK(child_task_runner_->BelongsToCurrentThread());
 
   const uint32_t req_buffer_count =
       output_dpb_size_ + kDpbOutputBufferExtraCount;
 
   if (buffers.size() < req_buffer_count) {
-    LOG(ERROR) << "AssignPictureBuffers(): Failed to provide requested picture"
-               << " buffers. (Got " << buffers.size()
-               << ", requested " << req_buffer_count << ")";
+    LOGF(ERROR) << "Failed to provide requested picture buffers. (Got "
+                << buffers.size() << ", requested " << req_buffer_count << ")";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
 
   gl::GLContext* gl_context = get_gl_context_cb_.Run();
   if (!gl_context || !make_context_current_cb_.Run()) {
-    LOG(ERROR) << "AssignPictureBuffers(): could not make context current";
+    LOGF(ERROR) << "could not make context current";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -351,7 +355,7 @@
   IOCTL_OR_ERROR_RETURN(VIDIOC_REQBUFS, &reqbufs);
 
   if (reqbufs.count != buffers.size()) {
-    DLOG(ERROR) << "Could not allocate enough output buffers";
+    DLOGF(ERROR) << "Could not allocate enough output buffers";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -368,16 +372,16 @@
             visible_size_, buffers.size(),
             base::Bind(&V4L2VideoDecodeAccelerator::ImageProcessorError,
                        base::Unretained(this)))) {
-      LOG(ERROR) << "Initialize image processor failed";
+      LOGF(ERROR) << "Initialize image processor failed";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
     DCHECK(image_processor_->output_allocated_size() == egl_image_size_);
     if (image_processor_->input_allocated_size() != coded_size_) {
-      LOG(ERROR) << "Image processor should be able to take the output coded "
-                 << "size of decoder " << coded_size_.ToString()
-                 << " without adjusting to "
-                 << image_processor_->input_allocated_size().ToString();
+      LOGF(ERROR) << "Image processor should be able to take the output coded "
+                  << "size of decoder " << coded_size_.ToString()
+                  << " without adjusting to "
+                  << image_processor_->input_allocated_size().ToString();
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -402,7 +406,7 @@
       std::vector<base::ScopedFD> fds = device_->GetDmabufsForV4L2Buffer(
           i, output_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
       if (fds.empty()) {
-        LOG(ERROR) << "Failed to get DMABUFs of decoder.";
+        LOGF(ERROR) << "Failed to get DMABUFs of decoder.";
         NOTIFY_ERROR(PLATFORM_FAILURE);
         return;
       }
@@ -413,7 +417,7 @@
     dmabuf_fds = egl_image_device_->GetDmabufsForV4L2Buffer(
         i, egl_image_planes_count_, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
     if (dmabuf_fds.empty()) {
-      LOG(ERROR) << "Failed to get DMABUFs for EGLImage.";
+      LOGF(ERROR) << "Failed to get DMABUFs for EGLImage.";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -422,7 +426,7 @@
         egl_display_, gl_context->GetHandle(), buffers[i].texture_ids()[0],
         egl_image_size_, i, egl_image_format_fourcc_, dmabuf_fds);
     if (egl_image == EGL_NO_IMAGE_KHR) {
-      LOG(ERROR) << "AssignPictureBuffers(): could not create EGLImageKHR";
+      LOGF(ERROR) << "could not create EGLImageKHR";
       // Ownership of EGLImages allocated in previous iterations of this loop
       // has been transferred to output_buffer_map_. After we error-out here
       // the destructor will handle their cleanup.
@@ -433,20 +437,19 @@
     output_record.egl_image = egl_image;
     output_record.picture_id = buffers[i].id();
     free_output_buffers_.push(i);
-    DVLOG(3) << "AssignPictureBuffers(): buffer[" << i
-             << "]: picture_id=" << output_record.picture_id;
+    DVLOGF(3) << "buffer[" << i << "]: picture_id=" << output_record.picture_id;
   }
 
   pictures_assigned_.Signal();
 }
 
 void V4L2VideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_buffer_id) {
-  DVLOG(3) << "ReusePictureBuffer(): picture_buffer_id=" << picture_buffer_id;
+  DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id;
   // Must be run on child thread, as we'll insert a sync in the EGL context.
   DCHECK(child_task_runner_->BelongsToCurrentThread());
 
   if (!make_context_current_cb_.Run()) {
-    LOG(ERROR) << "ReusePictureBuffer(): could not make context current";
+    LOGF(ERROR) << "could not make context current";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -456,7 +459,7 @@
 #if defined(ARCH_CPU_ARMEL)
   egl_sync = eglCreateSyncKHR(egl_display_, EGL_SYNC_FENCE_KHR, NULL);
   if (egl_sync == EGL_NO_SYNC_KHR) {
-    LOG(ERROR) << "ReusePictureBuffer(): eglCreateSyncKHR() failed";
+    LOGF(ERROR) << "eglCreateSyncKHR() failed";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -471,7 +474,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::Flush() {
-  DVLOG(3) << "Flush()";
+  DVLOGF(3);
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   decoder_thread_.message_loop()->PostTask(
       FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::FlushTask,
@@ -479,7 +482,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::Reset() {
-  DVLOG(3) << "Reset()";
+  DVLOGF(3);
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   decoder_thread_.message_loop()->PostTask(
       FROM_HERE, base::Bind(&V4L2VideoDecodeAccelerator::ResetTask,
@@ -487,7 +490,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::Destroy() {
-  DVLOG(3) << "Destroy()";
+  DVLOGF(3);
   DCHECK(child_task_runner_->BelongsToCurrentThread());
 
   // We're destroying; cancel all callbacks.
@@ -531,7 +534,7 @@
 
 void V4L2VideoDecodeAccelerator::DecodeTask(
     const BitstreamBuffer& bitstream_buffer) {
-  DVLOG(3) << "DecodeTask(): input_id=" << bitstream_buffer.id();
+  DVLOGF(3) << "input_id=" << bitstream_buffer.id();
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   TRACE_EVENT1("Video Decoder", "V4L2VDA::DecodeTask", "input_id",
@@ -548,11 +551,11 @@
     return;
 
   if (!bitstream_record->shm->Map()) {
-    LOG(ERROR) << "Decode(): could not map bitstream_buffer";
+    LOGF(ERROR) << "could not map bitstream_buffer";
     NOTIFY_ERROR(UNREADABLE_INPUT);
     return;
   }
-  DVLOG(3) << "DecodeTask(): mapped at=" << bitstream_record->shm->memory();
+  DVLOGF(3) << "mapped at=" << bitstream_record->shm->memory();
 
   if (decoder_state_ == kResetting || decoder_flushing_) {
     // In the case that we're resetting or flushing, we need to delay decoding
@@ -563,7 +566,7 @@
     if (decoder_delay_bitstream_buffer_id_ == -1)
       decoder_delay_bitstream_buffer_id_ = bitstream_record->input_id;
   } else if (decoder_state_ == kError) {
-    DVLOG(2) << "DecodeTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   }
 
@@ -574,7 +577,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::DecodeBufferTask() {
-  DVLOG(3) << "DecodeBufferTask()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   TRACE_EVENT0("Video Decoder", "V4L2VDA::DecodeBufferTask");
@@ -582,13 +585,13 @@
   decoder_decode_buffer_tasks_scheduled_--;
 
   if (decoder_state_ == kResetting) {
-    DVLOG(2) << "DecodeBufferTask(): early out: kResetting state";
+    DVLOGF(2) << "early out: kResetting state";
     return;
   } else if (decoder_state_ == kError) {
-    DVLOG(2) << "DecodeBufferTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   } else if (decoder_state_ == kChangingResolution) {
-    DVLOG(2) << "DecodeBufferTask(): early out: resolution change pending";
+    DVLOGF(2) << "early out: resolution change pending";
     return;
   }
 
@@ -608,12 +611,12 @@
     decoder_input_queue_.pop();
     const auto& shm = decoder_current_bitstream_buffer_->shm;
     if (shm) {
-      DVLOG(3) << "DecodeBufferTask(): reading input_id="
-               << decoder_current_bitstream_buffer_->input_id
-               << ", addr=" << shm->memory() << ", size=" << shm->size();
+      DVLOGF(3) << "reading input_id="
+                << decoder_current_bitstream_buffer_->input_id
+                << ", addr=" << shm->memory() << ", size=" << shm->size();
     } else {
       DCHECK_EQ(decoder_current_bitstream_buffer_->input_id, kFlushBufferId);
-      DVLOG(3) << "DecodeBufferTask(): reading input_id=kFlushBufferId";
+      DVLOGF(3) << "reading input_id=kFlushBufferId";
     }
   }
   bool schedule_task = false;
@@ -631,7 +634,7 @@
       schedule_task = FlushInputFrame();
 
     if (schedule_task && AppendToInputFrame(NULL, 0) && FlushInputFrame()) {
-      DVLOG(2) << "DecodeBufferTask(): enqueued flush buffer";
+      DVLOGF(2) << "enqueued flush buffer";
       decoder_partial_frame_pending_ = false;
       schedule_task = true;
     } else {
@@ -683,7 +686,7 @@
         decoder_current_bitstream_buffer_->bytes_used) {
       // Our current bitstream buffer is done; return it.
       int32_t input_id = decoder_current_bitstream_buffer_->input_id;
-      DVLOG(3) << "DecodeBufferTask(): finished input_id=" << input_id;
+      DVLOGF(3) << "finished input_id=" << input_id;
       // BitstreamBufferRef destructor calls NotifyEndOfBitstreamBuffer().
       decoder_current_bitstream_buffer_.reset();
     }
@@ -794,7 +797,7 @@
 bool V4L2VideoDecodeAccelerator::DecodeBufferInitial(const void* data,
                                                      size_t size,
                                                      size_t* endpos) {
-  DVLOG(3) << "DecodeBufferInitial(): data=" << data << ", size=" << size;
+  DVLOGF(3) << "data=" << data << ", size=" << size;
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   DCHECK_NE(decoder_state_, kDecoding);
@@ -831,7 +834,7 @@
 
   // Run this initialization only on first startup.
   if (decoder_state_ == kInitialized) {
-    DVLOG(3) << "DecodeBufferInitial(): running initialization";
+    DVLOGF(3) << "running initialization";
     // Success! Setup our parameters.
     if (!CreateBuffersForFormat(format, visible_size))
       return false;
@@ -844,7 +847,7 @@
 
 bool V4L2VideoDecodeAccelerator::DecodeBufferContinue(const void* data,
                                                       size_t size) {
-  DVLOG(3) << "DecodeBufferContinue(): data=" << data << ", size=" << size;
+  DVLOGF(3) << "data=" << data << ", size=" << size;
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_EQ(decoder_state_, kDecoding);
 
@@ -856,7 +859,7 @@
 
 bool V4L2VideoDecodeAccelerator::AppendToInputFrame(const void* data,
                                                     size_t size) {
-  DVLOG(3) << "AppendToInputFrame()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   DCHECK_NE(decoder_state_, kResetting);
@@ -882,7 +885,7 @@
       Dequeue();
       if (free_input_buffers_.empty()) {
         // Nope!
-        DVLOG(2) << "AppendToInputFrame(): stalled for input buffers";
+        DVLOGF(2) << "stalled for input buffers";
         return false;
       }
     }
@@ -907,7 +910,7 @@
   // Copy in to the buffer.
   InputRecord& input_record = input_buffer_map_[decoder_current_input_buffer_];
   if (size > input_record.length - input_record.bytes_used) {
-    LOG(ERROR) << "AppendToInputFrame(): over-size frame, erroring";
+    LOGF(ERROR) << "over-size frame, erroring";
     NOTIFY_ERROR(UNREADABLE_INPUT);
     return false;
   }
@@ -920,7 +923,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::FlushInputFrame() {
-  DVLOG(3) << "FlushInputFrame()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   DCHECK_NE(decoder_state_, kResetting);
@@ -948,8 +951,7 @@
   // Queue it.
   input_ready_queue_.push(decoder_current_input_buffer_);
   decoder_current_input_buffer_ = -1;
-  DVLOG(3) << "FlushInputFrame(): submitting input_id="
-           << input_record.input_id;
+  DVLOGF(3) << "submitting input_id=" << input_record.input_id;
   // Enqueue once since there's new available input for it.
   Enqueue();
 
@@ -957,19 +959,19 @@
 }
 
 void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) {
-  DVLOG(3) << "ServiceDeviceTask()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   TRACE_EVENT0("Video Decoder", "V4L2VDA::ServiceDeviceTask");
 
   if (decoder_state_ == kResetting) {
-    DVLOG(2) << "ServiceDeviceTask(): early out: kResetting state";
+    DVLOGF(2) << "early out: kResetting state";
     return;
   } else if (decoder_state_ == kError) {
-    DVLOG(2) << "ServiceDeviceTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   } else if (decoder_state_ == kChangingResolution) {
-    DVLOG(2) << "ServiceDeviceTask(): early out: kChangingResolution state";
+    DVLOGF(2) << "early out: kChangingResolution state";
     return;
   }
 
@@ -1021,7 +1023,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::Enqueue() {
-  DVLOG(3) << "Enqueue()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   TRACE_EVENT0("Video Decoder", "V4L2VDA::Enqueue");
@@ -1036,7 +1038,7 @@
     // We just started up a previously empty queue.
     // Queue state changed; signal interrupt.
     if (!device_->SetDevicePollInterrupt()) {
-      PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
+      PLOGF(ERROR) << "SetDevicePollInterrupt failed";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -1058,7 +1060,7 @@
     // We just started up a previously empty queue.
     // Queue state changed; signal interrupt.
     if (!device_->SetDevicePollInterrupt()) {
-      PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
+      PLOGF(ERROR) << "SetDevicePollInterrupt(): failed";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -1074,7 +1076,7 @@
 bool V4L2VideoDecodeAccelerator::DequeueResolutionChangeEvent() {
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
-  DVLOG(3) << "DequeueResolutionChangeEvent()";
+  DVLOGF(3);
 
   struct v4l2_event ev;
   memset(&ev, 0, sizeof(ev));
@@ -1082,20 +1084,19 @@
   while (device_->Ioctl(VIDIOC_DQEVENT, &ev) == 0) {
     if (ev.type == V4L2_EVENT_SOURCE_CHANGE) {
       if (ev.u.src_change.changes & V4L2_EVENT_SRC_CH_RESOLUTION) {
-        DVLOG(3)
-            << "DequeueResolutionChangeEvent(): got resolution change event.";
+        DVLOGF(3) << "got resolution change event.";
         return true;
       }
     } else {
-      LOG(ERROR) << "DequeueResolutionChangeEvent(): got an event (" << ev.type
-                 << ") we haven't subscribed to.";
+      LOGF(ERROR) << "got an event (" << ev.type
+                  << ") we haven't subscribed to.";
     }
   }
   return false;
 }
 
 void V4L2VideoDecodeAccelerator::Dequeue() {
-  DVLOG(3) << "Dequeue()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_NE(decoder_state_, kUninitialized);
   TRACE_EVENT0("Video Decoder", "V4L2VDA::Dequeue");
@@ -1117,7 +1118,7 @@
         // EAGAIN if we're just out of buffers to dequeue.
         break;
       }
-      PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
+      PLOGF(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -1148,7 +1149,7 @@
         // EAGAIN if we're just out of buffers to dequeue.
         break;
       }
-      PLOG(ERROR) << "Dequeue(): ioctl() failed: VIDIOC_DQBUF";
+      PLOGF(ERROR) << "ioctl() failed: VIDIOC_DQBUF";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return;
     }
@@ -1164,8 +1165,8 @@
     } else {
       int32_t bitstream_buffer_id = dqbuf.timestamp.tv_sec;
       DCHECK_GE(bitstream_buffer_id, 0);
-      DVLOG(3) << "Dequeue output buffer: dqbuf index=" << dqbuf.index
-               << " bitstream input_id=" << bitstream_buffer_id;
+      DVLOGF(3) << "Dequeue output buffer: dqbuf index=" << dqbuf.index
+                << " bitstream input_id=" << bitstream_buffer_id;
       if (image_processor_device_) {
         output_record.state = kAtProcessor;
         image_processor_bitstream_buffer_ids_.push(bitstream_buffer_id);
@@ -1203,7 +1204,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::EnqueueInputRecord() {
-  DVLOG(3) << "EnqueueInputRecord()";
+  DVLOGF(3);
   DCHECK(!input_ready_queue_.empty());
 
   // Enqueue an input (VIDEO_OUTPUT) buffer.
@@ -1225,13 +1226,13 @@
   input_ready_queue_.pop();
   input_record.at_device = true;
   input_buffer_queued_count_++;
-  DVLOG(3) << "EnqueueInputRecord(): enqueued input_id="
-           << input_record.input_id << " size=" << input_record.bytes_used;
+  DVLOGF(3) << "enqueued input_id=" << input_record.input_id
+            << " size=" << input_record.bytes_used;
   return true;
 }
 
 bool V4L2VideoDecodeAccelerator::EnqueueOutputRecord() {
-  DVLOG(3) << "EnqueueOutputRecord()";
+  DVLOGF(3);
   DCHECK(!free_output_buffers_.empty());
 
   // Enqueue an output (VIDEO_CAPTURE) buffer.
@@ -1249,10 +1250,10 @@
     if (eglClientWaitSyncKHR(egl_display_, output_record.egl_sync, 0,
                              EGL_FOREVER_KHR) == EGL_FALSE) {
       // This will cause tearing, but is safe otherwise.
-      DLOG(WARNING) << __func__ << " eglClientWaitSyncKHR failed!";
+      DLOGF(WARNING) << "eglClientWaitSyncKHR failed!";
     }
     if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
-      LOG(ERROR) << __func__ << " eglDestroySyncKHR failed!";
+      LOGF(ERROR) << "eglDestroySyncKHR failed!";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return false;
     }
@@ -1279,19 +1280,18 @@
 void V4L2VideoDecodeAccelerator::ReusePictureBufferTask(
     int32_t picture_buffer_id,
     std::unique_ptr<EGLSyncKHRRef> egl_sync_ref) {
-  DVLOG(3) << "ReusePictureBufferTask(): picture_buffer_id="
-           << picture_buffer_id;
+  DVLOGF(3) << "picture_buffer_id=" << picture_buffer_id;
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   TRACE_EVENT0("Video Decoder", "V4L2VDA::ReusePictureBufferTask");
 
   // We run ReusePictureBufferTask even if we're in kResetting.
   if (decoder_state_ == kError) {
-    DVLOG(2) << "ReusePictureBufferTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   }
 
   if (decoder_state_ == kChangingResolution) {
-    DVLOG(2) << "ReusePictureBufferTask(): early out: kChangingResolution";
+    DVLOGF(2) << "early out: kChangingResolution";
     return;
   }
 
@@ -1306,14 +1306,14 @@
     // posted to us by the client. In that case just ignore this (we've already
     // dismissed it and accounted for that) and let the sync object get
     // destroyed.
-    DVLOG(4) << "ReusePictureBufferTask(): got picture id= "
-             << picture_buffer_id << " not in use (anymore?).";
+    DVLOGF(4) << "got picture id= " << picture_buffer_id
+              << " not in use (anymore?).";
     return;
   }
 
   OutputRecord& output_record = output_buffer_map_[index];
   if (output_record.state != kAtClient) {
-    LOG(ERROR) << "ReusePictureBufferTask(): picture_buffer_id not reusable";
+    LOGF(ERROR) << "picture_buffer_id not reusable";
     NOTIFY_ERROR(INVALID_ARGUMENT);
     return;
   }
@@ -1330,19 +1330,19 @@
 }
 
 void V4L2VideoDecodeAccelerator::FlushTask() {
-  DVLOG(3) << "FlushTask()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   TRACE_EVENT0("Video Decoder", "V4L2VDA::FlushTask");
 
   // Flush outstanding buffers.
   if (decoder_state_ == kInitialized || decoder_state_ == kAfterReset) {
     // There's nothing in the pipe, so return done immediately.
-    DVLOG(3) << "FlushTask(): returning flush";
+    DVLOGF(3) << "returning flush";
     child_task_runner_->PostTask(FROM_HERE,
                                  base::Bind(&Client::NotifyFlushDone, client_));
     return;
   } else if (decoder_state_ == kError) {
-    DVLOG(2) << "FlushTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   }
 
@@ -1399,7 +1399,7 @@
 
   decoder_delay_bitstream_buffer_id_ = -1;
   decoder_flushing_ = false;
-  DVLOG(3) << "NotifyFlushDoneIfNeeded(): returning flush";
+  DVLOGF(3) << "returning flush";
   child_task_runner_->PostTask(FROM_HERE,
                                base::Bind(&Client::NotifyFlushDone, client_));
 
@@ -1408,12 +1408,12 @@
 }
 
 void V4L2VideoDecodeAccelerator::ResetTask() {
-  DVLOG(3) << "ResetTask()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetTask");
 
   if (decoder_state_ == kError) {
-    DVLOG(2) << "ResetTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   }
 
@@ -1468,12 +1468,12 @@
 }
 
 void V4L2VideoDecodeAccelerator::ResetDoneTask() {
-  DVLOG(3) << "ResetDoneTask()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   TRACE_EVENT0("Video Decoder", "V4L2VDA::ResetDoneTask");
 
   if (decoder_state_ == kError) {
-    DVLOG(2) << "ResetDoneTask(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   }
 
@@ -1505,7 +1505,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::DestroyTask() {
-  DVLOG(3) << "DestroyTask()";
+  DVLOGF(3);
   TRACE_EVENT0("Video Decoder", "V4L2VDA::DestroyTask");
 
   // DestroyTask() should run regardless of decoder_state_.
@@ -1527,13 +1527,13 @@
 }
 
 bool V4L2VideoDecodeAccelerator::StartDevicePoll() {
-  DVLOG(3) << "StartDevicePoll()";
+  DVLOGF(3);
   DCHECK(!device_poll_thread_.IsRunning());
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
 
   // Start up the device poll thread and schedule its first DevicePollTask().
   if (!device_poll_thread_.Start()) {
-    LOG(ERROR) << "StartDevicePoll(): Device thread failed to start";
+    LOGF(ERROR) << "Device thread failed to start";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1545,7 +1545,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::StopDevicePoll() {
-  DVLOG(3) << "StopDevicePoll()";
+  DVLOGF(3);
 
   if (!device_poll_thread_.IsRunning())
     return true;
@@ -1555,7 +1555,7 @@
 
   // Signal the DevicePollTask() to stop, and stop the device poll thread.
   if (!device_->SetDevicePollInterrupt()) {
-    PLOG(ERROR) << "SetDevicePollInterrupt(): failed";
+    PLOGF(ERROR) << "SetDevicePollInterrupt(): failed";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
@@ -1565,12 +1565,12 @@
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return false;
   }
-  DVLOG(3) << "StopDevicePoll(): device poll stopped";
+  DVLOGF(3) << "device poll stopped";
   return true;
 }
 
 bool V4L2VideoDecodeAccelerator::StopOutputStream() {
-  DVLOG(3) << "StopOutputStream()";
+  DVLOGF(3);
   if (!output_streamon_)
     return true;
 
@@ -1594,7 +1594,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::StopInputStream() {
-  DVLOG(3) << "StopInputStream()";
+  DVLOGF(3);
   if (!input_streamon_)
     return true;
 
@@ -1622,7 +1622,7 @@
   DCHECK_NE(decoder_state_, kUninitialized);
   DCHECK_NE(decoder_state_, kResetting);
 
-  DVLOG(3) << "Initiate resolution change";
+  DVLOGF(3) << "Initiate resolution change";
 
   if (!(StopDevicePoll() && StopOutputStream()))
     return;
@@ -1630,7 +1630,7 @@
   decoder_state_ = kChangingResolution;
 
   if (!image_processor_bitstream_buffer_ids_.empty()) {
-    DVLOG(3) << "Wait image processor to finish before destroying buffers.";
+    DVLOGF(3) << "Wait image processor to finish before destroying buffers.";
     return;
   }
 
@@ -1645,10 +1645,10 @@
 void V4L2VideoDecodeAccelerator::FinishResolutionChange() {
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_EQ(decoder_state_, kChangingResolution);
-  DVLOG(3) << "FinishResolutionChange()";
+  DVLOGF(3);
 
   if (decoder_state_ == kError) {
-    DVLOG(2) << "FinishResolutionChange(): early out: kError state";
+    DVLOGF(2) << "early out: kError state";
     return;
   }
 
@@ -1657,13 +1657,13 @@
   gfx::Size visible_size;
   bool ret = GetFormatInfo(&format, &visible_size, &again);
   if (!ret || again) {
-    LOG(ERROR) << "Couldn't get format information after resolution change";
+    LOGF(ERROR) << "Couldn't get format information after resolution change";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
 
   if (!CreateBuffersForFormat(format, visible_size)) {
-    LOG(ERROR) << "Couldn't reallocate buffers after resolution change";
+    LOGF(ERROR) << "Couldn't reallocate buffers after resolution change";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -1684,7 +1684,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::DevicePollTask(bool poll_device) {
-  DVLOG(3) << "DevicePollTask()";
+  DVLOGF(3);
   DCHECK_EQ(device_poll_thread_.message_loop(), base::MessageLoop::current());
   TRACE_EVENT0("Video Decoder", "V4L2VDA::DevicePollTask");
 
@@ -1703,7 +1703,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::NotifyError(Error error) {
-  DVLOG(2) << "NotifyError()";
+  DVLOGF(2);
 
   if (!child_task_runner_->BelongsToCurrentThread()) {
     child_task_runner_->PostTask(
@@ -1751,7 +1751,7 @@
       *again = true;
       return true;
     } else {
-      PLOG(ERROR) << __func__ << "(): ioctl() failed: VIDIOC_G_FMT";
+      PLOGF(ERROR) << "ioctl() failed: VIDIOC_G_FMT";
       NOTIFY_ERROR(PLATFORM_FAILURE);
       return false;
     }
@@ -1759,7 +1759,7 @@
 
   // Make sure we are still getting the format we set on initialization.
   if (format->fmt.pix_mp.pixelformat != output_format_fourcc_) {
-    LOG(ERROR) << "Unexpected format from G_FMT on output";
+    LOGF(ERROR) << "Unexpected format from G_FMT on output";
     return false;
   }
 
@@ -1783,17 +1783,16 @@
     egl_image_planes_count_ = 0;
     if (!processor.TryOutputFormat(egl_image_format_fourcc_, &egl_image_size_,
                                    &egl_image_planes_count_)) {
-      LOG(ERROR) << "Fail to get output size and plane count of processor";
+      LOGF(ERROR) << "Fail to get output size and plane count of processor";
       return false;
     }
   } else {
     egl_image_size_ = coded_size_;
     egl_image_planes_count_ = output_planes_count_;
   }
-  DVLOG(3) << "CreateBuffersForFormat(): new resolution: "
-           << coded_size_.ToString()
-           << ", visible size: " << visible_size_.ToString()
-           << ", EGLImage size: " << egl_image_size_.ToString();
+  DVLOGF(3) << "new resolution: " << coded_size_.ToString()
+            << ", visible size: " << visible_size_.ToString()
+            << ", EGLImage size: " << egl_image_size_.ToString();
 
   return CreateOutputBuffers();
 }
@@ -1807,27 +1806,27 @@
   crop_arg.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
 
   if (device_->Ioctl(VIDIOC_G_CROP, &crop_arg) != 0) {
-    PLOG(ERROR) << "GetVisibleSize(): ioctl() VIDIOC_G_CROP failed";
+    PLOGF(ERROR) << "ioctl() VIDIOC_G_CROP failed";
     return coded_size;
   }
 
   gfx::Rect rect(crop_arg.c.left, crop_arg.c.top, crop_arg.c.width,
                  crop_arg.c.height);
-  DVLOG(3) << "visible rectangle is " << rect.ToString();
+  DVLOGF(3) << "visible rectangle is " << rect.ToString();
   if (!gfx::Rect(coded_size).Contains(rect)) {
-    DLOG(ERROR) << "visible rectangle " << rect.ToString()
-                << " is not inside coded size " << coded_size.ToString();
+    DLOGF(ERROR) << "visible rectangle " << rect.ToString()
+                 << " is not inside coded size " << coded_size.ToString();
     return coded_size;
   }
   if (rect.IsEmpty()) {
-    DLOG(ERROR) << "visible size is empty";
+    DLOGF(ERROR) << "visible size is empty";
     return coded_size;
   }
 
   // Chrome assume picture frame is coded at (0, 0).
   if (!rect.origin().IsOrigin()) {
-    DLOG(ERROR) << "Unexpected visible rectangle " << rect.ToString()
-                << ", top-left is not origin";
+    DLOGF(ERROR) << "Unexpected visible rectangle " << rect.ToString()
+                 << ", top-left is not origin";
     return coded_size;
   }
 
@@ -1835,7 +1834,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
-  DVLOG(3) << "CreateInputBuffers()";
+  DVLOGF(3);
   // We always run this as we prepare to initialize.
   DCHECK_EQ(decoder_state_, kUninitialized);
   DCHECK(!input_streamon_);
@@ -1868,7 +1867,7 @@
                                   MAP_SHARED,
                                   buffer.m.planes[0].m.mem_offset);
     if (address == MAP_FAILED) {
-      PLOG(ERROR) << "CreateInputBuffers(): mmap() failed";
+      PLOGF(ERROR) << "mmap() failed";
       return false;
     }
     input_buffer_map_[i].address = address;
@@ -1914,8 +1913,8 @@
   }
 
   if (!is_format_supported) {
-    DVLOG(1) << "Input fourcc " << input_format_fourcc
-             << " not supported by device.";
+    DVLOGF(1) << "Input fourcc " << input_format_fourcc
+              << " not supported by device.";
     return false;
   }
 
@@ -1941,20 +1940,20 @@
   }
 
   if (output_format_fourcc_ == 0) {
-    DVLOG(1) << "Could not find a usable output format. Try image processor";
+    DVLOGF(1) << "Could not find a usable output format. Try image processor";
     image_processor_device_ = V4L2Device::Create(V4L2Device::kImageProcessor);
     if (!image_processor_device_) {
-      DVLOG(1) << "No image processor device.";
+      DVLOGF(1) << "No image processor device.";
       return false;
     }
     output_format_fourcc_ = FindImageProcessorInputFormat();
     if (output_format_fourcc_ == 0) {
-      LOG(ERROR) << "Couldn't find a usable input format from image processor";
+      LOGF(ERROR) << "Can't find a usable input format from image processor";
       return false;
     }
     egl_image_format_fourcc_ = FindImageProcessorOutputFormat();
     if (egl_image_format_fourcc_ == 0) {
-      LOG(ERROR) << "Couldn't find a usable output format from image processor";
+      LOGF(ERROR) << "Can't find a usable output format from image processor";
       return false;
     }
     egl_image_device_ = image_processor_device_;
@@ -1962,7 +1961,7 @@
     egl_image_format_fourcc_ = output_format_fourcc_;
     egl_image_device_ = device_;
   }
-  DVLOG(2) << __func__ << ": Output format=" << output_format_fourcc_;
+  DVLOGF(2) << "Output format=" << output_format_fourcc_;
 
   // Just set the fourcc for output; resolution, etc., will come from the
   // driver once it extracts it from the stream.
@@ -1985,7 +1984,7 @@
     if (std::find(processor_input_formats.begin(),
                   processor_input_formats.end(),
                   fmtdesc.pixelformat) != processor_input_formats.end()) {
-      DVLOG(1) << "Image processor input format=" << fmtdesc.pixelformat;
+      DVLOGF(1) << "Image processor input format=" << fmtdesc.pixelformat;
       return fmtdesc.pixelformat;
     }
     ++fmtdesc.index;
@@ -1999,7 +1998,7 @@
       image_processor.GetSupportedOutputFormats();
   for (uint32_t processor_output_format : processor_output_formats) {
     if (device_->CanCreateEGLImageFrom(processor_output_format)) {
-      DVLOG(1) << "Image processor output format=" << processor_output_format;
+      DVLOGF(1) << "Image processor output format=" << processor_output_format;
       return processor_output_format;
     }
   }
@@ -2008,7 +2007,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::CreateOutputBuffers() {
-  DVLOG(3) << "CreateOutputBuffers()";
+  DVLOGF(3);
   DCHECK(decoder_state_ == kInitialized ||
          decoder_state_ == kChangingResolution);
   DCHECK(!output_streamon_);
@@ -2024,9 +2023,8 @@
   // Output format setup in Initialize().
 
   const uint32_t buffer_count = output_dpb_size_ + kDpbOutputBufferExtraCount;
-  DVLOG(3) << "CreateOutputBuffers(): ProvidePictureBuffers(): "
-           << "buffer_count=" << buffer_count
-           << ", coded_size=" << egl_image_size_.ToString();
+  DVLOGF(3) << "buffer_count=" << buffer_count
+            << ", coded_size=" << egl_image_size_.ToString();
 
   child_task_runner_->PostTask(
       FROM_HERE, base::Bind(&Client::ProvidePictureBuffers, client_,
@@ -2053,7 +2051,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::DestroyInputBuffers() {
-  DVLOG(3) << "DestroyInputBuffers()";
+  DVLOGF(3);
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   DCHECK(!input_streamon_);
 
@@ -2076,7 +2074,7 @@
 }
 
 bool V4L2VideoDecodeAccelerator::DestroyOutputBuffers() {
-  DVLOG(3) << "DestroyOutputBuffers()";
+  DVLOGF(3);
   DCHECK(child_task_runner_->BelongsToCurrentThread());
   DCHECK(!output_streamon_);
   bool success = true;
@@ -2087,20 +2085,19 @@
     if (output_record.egl_image != EGL_NO_IMAGE_KHR) {
       if (egl_image_device_->DestroyEGLImage(
               egl_display_, output_record.egl_image) != EGL_TRUE) {
-        DVLOG(1) << __func__ << " DestroyEGLImage failed.";
+        DVLOGF(1) << "DestroyEGLImage failed.";
         success = false;
       }
     }
 
     if (output_record.egl_sync != EGL_NO_SYNC_KHR) {
       if (eglDestroySyncKHR(egl_display_, output_record.egl_sync) != EGL_TRUE) {
-        DVLOG(1) << __func__ << " eglDestroySyncKHR failed.";
+        DVLOGF(1) << "eglDestroySyncKHR failed.";
         success = false;
       }
     }
 
-    DVLOG(1) << "DestroyOutputBuffers(): dismissing PictureBuffer id="
-             << output_record.picture_id;
+    DVLOGF(1) << "dismissing PictureBuffer id=" << output_record.picture_id;
     child_task_runner_->PostTask(
         FROM_HERE, base::Bind(&Client::DismissPictureBuffer, client_,
                               output_record.picture_id));
@@ -2115,7 +2112,7 @@
   reqbufs.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   reqbufs.memory = V4L2_MEMORY_MMAP;
   if (device_->Ioctl(VIDIOC_REQBUFS, &reqbufs) != 0) {
-    PLOG(ERROR) << "DestroyOutputBuffers() ioctl() failed: VIDIOC_REQBUFS";
+    PLOGF(ERROR) << "ioctl() failed: VIDIOC_REQBUFS";
     success = false;
   }
 
@@ -2132,10 +2129,10 @@
 
 void V4L2VideoDecodeAccelerator::ResolutionChangeDestroyBuffers() {
   DCHECK(child_task_runner_->BelongsToCurrentThread());
-  DVLOG(3) << "ResolutionChangeDestroyBuffers()";
+  DVLOGF(3);
 
   if (!DestroyOutputBuffers()) {
-    LOG(ERROR) << __func__ << " Failed destroying output buffers.";
+    LOGF(ERROR) << "Failed destroying output buffers.";
     NOTIFY_ERROR(PLATFORM_FAILURE);
     return;
   }
@@ -2147,7 +2144,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::SendPictureReady() {
-  DVLOG(3) << "SendPictureReady()";
+  DVLOGF(3);
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   bool resetting_or_flushing =
       (decoder_state_ == kResetting || decoder_flushing_);
@@ -2163,11 +2160,10 @@
           base::Bind(&Client::PictureReady, decode_client_, picture));
       pending_picture_ready_.pop();
     } else if (!cleared || resetting_or_flushing) {
-      DVLOG(3) << "SendPictureReady()"
-               << ". cleared=" << pending_picture_ready_.front().cleared
-               << ", decoder_state_=" << decoder_state_
-               << ", decoder_flushing_=" << decoder_flushing_
-               << ", picture_clearing_count_=" << picture_clearing_count_;
+      DVLOGF(3) << "cleared=" << pending_picture_ready_.front().cleared
+                << ", decoder_state_=" << decoder_state_
+                << ", decoder_flushing_=" << decoder_flushing_
+                << ", picture_clearing_count_=" << picture_clearing_count_;
       // If the picture is not cleared, post it to the child thread because it
       // has to be cleared in the child thread. A picture only needs to be
       // cleared once. If the decoder is resetting or flushing, send all
@@ -2190,7 +2186,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::PictureCleared() {
-  DVLOG(3) << "PictureCleared(). clearing count=" << picture_clearing_count_;
+  DVLOGF(3) << "clearing count=" << picture_clearing_count_;
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_GT(picture_clearing_count_, 0);
   picture_clearing_count_--;
@@ -2199,8 +2195,8 @@
 
 void V4L2VideoDecodeAccelerator::FrameProcessed(int32_t bitstream_buffer_id,
                                                 int output_buffer_index) {
-  DVLOG(3) << __func__ << ": output_buffer_index=" << output_buffer_index
-           << ", bitstream_buffer_id=" << bitstream_buffer_id;
+  DVLOGF(3) << "output_buffer_index=" << output_buffer_index
+            << ", bitstream_buffer_id=" << bitstream_buffer_id;
   DCHECK_EQ(decoder_thread_.message_loop(), base::MessageLoop::current());
   DCHECK_GE(output_buffer_index, 0);
   DCHECK_LT(output_buffer_index, static_cast<int>(output_buffer_map_.size()));
@@ -2209,7 +2205,7 @@
   DCHECK_EQ(output_record.state, kAtProcessor);
   if (!image_processor_bitstream_buffer_ids_.empty() &&
       image_processor_bitstream_buffer_ids_.front() == bitstream_buffer_id) {
-    DVLOG(3) << __func__ << ": picture_id=" << output_record.picture_id;
+    DVLOGF(3) << "picture_id=" << output_record.picture_id;
     DCHECK_NE(output_record.egl_image, EGL_NO_IMAGE_KHR);
     DCHECK_NE(output_record.picture_id, -1);
     // Send the processed frame to render.
@@ -2228,8 +2224,8 @@
         StartResolutionChange();
     }
   } else {
-    DVLOG(2) << "Bitstream buffer id " << bitstream_buffer_id << " not found "
-             << "because of Reset. Drop the buffer";
+    DVLOGF(2) << "Bitstream buffer id " << bitstream_buffer_id << " not found "
+              << "because of Reset. Drop the buffer";
     output_record.state = kFree;
     free_output_buffers_.push(output_buffer_index);
     Enqueue();
@@ -2237,7 +2233,7 @@
 }
 
 void V4L2VideoDecodeAccelerator::ImageProcessorError() {
-  LOG(ERROR) << "Image processor error";
+  LOGF(ERROR) << "Image processor error";
   NOTIFY_ERROR(PLATFORM_FAILURE);
 }
 
diff --git a/media/media.gyp b/media/media.gyp
index a553800..6bfddab 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -49,7 +49,6 @@
     ],
   },
   'includes': [
-    'capture/capture.gypi',
     'media_cdm.gypi',
     'media_variables.gypi',
   ],
@@ -102,11 +101,7 @@
       'include_dirs': [
         '..',
       ],
-      'includes': [
-        'capture/capture.gypi',
-      ],
       'sources': [
-        '<@(capture_sources)',
         'audio/agc_audio_stream.h',
         'audio/alsa/alsa_input.cc',
         'audio/alsa/alsa_input.h',
@@ -475,8 +470,6 @@
         'base/video_util.h',
         'base/wall_clock_time_source.cc',
         'base/wall_clock_time_source.h',
-        'base/win/mf_initializer.cc',
-        'base/win/mf_initializer.h',
         'base/yuv_convert.cc',
         'base/yuv_convert.h',
         'cdm/aes_decryptor.cc',
@@ -713,11 +706,9 @@
         }],
         ['OS=="android"', {
           'dependencies': [
-            'capture_java',
             'media_android_jni_headers',
             'media_java',
             'player_android',
-            'video_capture_android_jni_headers',
           ],
           'sources!': [
             'base/audio_video_metadata_extractor.cc',
@@ -820,12 +811,6 @@
                 'audio/cras/cras_unified.h',
               ],
             }],
-
-            ['use_udev==1', {
-              'dependencies': [
-                '<(DEPTH)/device/udev_linux/udev.gyp:udev_linux',
-              ],
-            }],
           ],
         }],
         ['OS!="linux"', {
@@ -923,10 +908,6 @@
           ],
         }],
         ['OS=="mac"', {
-          'dependencies': [
-            '<(DEPTH)/third_party/decklink/decklink.gyp:decklink',
-          ],
-
           'link_settings': {
             'libraries': [
               '$(SDKROOT)/System/Library/Frameworks/AudioToolbox.framework',
@@ -939,39 +920,6 @@
           },
         }],
         ['OS=="win"', {
-          'link_settings':  {
-            'libraries': [
-              '-ldxguid.lib',
-              '-lmf.lib',
-              '-lmfplat.lib',
-              '-lmfreadwrite.lib',
-              '-lmfuuid.lib',
-              '-lsetupapi.lib',
-              '-lwinmm.lib',
-            ],
-          },
-          # Specify delayload for media.dll.
-          'msvs_settings': {
-            'VCLinkerTool': {
-              'DelayLoadDLLs': [
-                'mf.dll',
-                'mfplat.dll',
-                'mfreadwrite.dll',
-              ],
-            },
-          },
-          # Specify delayload for components that link with media.lib.
-          'all_dependent_settings': {
-            'msvs_settings': {
-              'VCLinkerTool': {
-                'DelayLoadDLLs': [
-                  'mf.dll',
-                  'mfplat.dll',
-                  'mfreadwrite.dll',
-                ],
-              },
-            },
-          },
           # TODO(wolenetz): Fix size_t to int truncations in win64. See
           # http://crbug.com/171009
           'conditions': [
@@ -1127,6 +1075,8 @@
       'type': '<(gtest_target_type)',
       'dependencies': [
         'audio_test_config',
+        # TODO(mcasas): Remove this entry after https://crbug.com/618718.
+        'capture/capture.gyp:unittests',
         'cdm_paths',
         'media',
         'media_features',
@@ -1149,7 +1099,6 @@
         '../url/url.gyp:url_lib',
       ],
       'sources': [
-        '<@(capture_unittests_sources)',
         'base/android/access_unit_queue_unittest.cc',
         'base/android/media_codec_decoder_unittest.cc',
         'base/android/media_drm_bridge_unittest.cc',
@@ -1545,12 +1494,14 @@
     },
     {
       # GN version: //media:audio_unittests
-      # For running the subset of media_unittests that might require audio
+      # For running the subset of tests that might require audio
       # hardware separately on GPU bots. media_unittests includes these too.
       'target_name': 'audio_unittests',
       'type': '<(gtest_target_type)',
       'dependencies': [
         'audio_test_config',
+        # TODO(mcasas): Remove this entry after https://crbug.com/618718.
+        'capture/capture.gyp:unittests',
         'media_test_support',
         '../base/base.gyp:test_support_base',
         '../testing/gmock.gyp:gmock',
@@ -1748,6 +1699,56 @@
         },
       ], # targets
     }],
+    ['OS=="win"', {
+      'targets': [
+        {
+          # GN version: //media/base/win
+          'target_name': 'mf_initializer',
+          'type': '<(component)',
+          'include_dirs': [ '..', ],
+          'defines': [ 'MF_INITIALIZER_IMPLEMENTATION', ],
+          'sources': [
+            'base/win/mf_initializer_export.h',
+            'base/win/mf_initializer.cc',
+            'base/win/mf_initializer.h',
+          ],
+          'dependencies': [
+            '../base/base.gyp:base',
+          ],
+          'link_settings':  {
+            'libraries': [
+              '-ldxguid.lib',
+              '-lmf.lib',
+              '-lmfplat.lib',
+              '-lmfreadwrite.lib',
+              '-lmfuuid.lib',
+              '-lsetupapi.lib',
+              '-lwinmm.lib',
+            ],
+          },
+          'msvs_settings': {
+            'VCLinkerTool': {
+              'DelayLoadDLLs': [
+                'mf.dll',
+                'mfplat.dll',
+                'mfreadwrite.dll',
+              ],
+            },
+          },
+          'all_dependent_settings': {
+            'msvs_settings': {
+              'VCLinkerTool': {
+                'DelayLoadDLLs': [
+                  'mf.dll',
+                  'mfplat.dll',
+                  'mfreadwrite.dll',
+                ],
+              },
+            },
+          },
+        },
+      ],
+    }],
     ['OS=="android"', {
       'targets': [
         {
@@ -1755,7 +1756,6 @@
           'target_name': 'media_unittests_apk',
           'type': 'none',
           'dependencies': [
-            'capture_java',
             'media_java',
             'media_unittests',
           ],
@@ -1770,7 +1770,6 @@
           'target_name': 'media_perftests_apk',
           'type': 'none',
           'dependencies': [
-            'capture_java',
             'media_java',
             'media_perftests',
           ],
@@ -1799,19 +1798,6 @@
           'includes': ['../build/jni_generator.gypi'],
         },
         {
-          # GN: //media/capture/video/android:capture_jni_headers
-          'target_name': 'video_capture_android_jni_headers',
-          'type': 'none',
-          'sources': [
-            'capture/video/android/java/src/org/chromium/media/VideoCapture.java',
-            'capture/video/android/java/src/org/chromium/media/VideoCaptureFactory.java',
-          ],
-          'variables': {
-            'jni_gen_package': 'media',
-          },
-          'includes': ['../build/jni_generator.gypi'],
-        },
-        {
           # GN: //media/base/android:android
           'target_name': 'player_android',
           'type': 'static_library',
@@ -1901,23 +1887,6 @@
           ],
         },
         {
-          # GN: //media/capture/video/android:capture_java
-          'target_name': 'capture_java',
-          'type': 'none',
-          'dependencies': [
-            '../base/base.gyp:base',
-            'media_android_captureapitype',
-            'media_android_imageformat',
-          ],
-          'export_dependent_settings': [
-            '../base/base.gyp:base',
-          ],
-          'variables': {
-            'java_in_dir': 'capture/video/android/java',
-          },
-          'includes': ['../build/java.gypi'],
-        },
-        {
           # GN: //media/base/android:media_java
           'target_name': 'media_java',
           'type': 'none',
@@ -1932,24 +1901,6 @@
           },
           'includes': ['../build/java.gypi'],
         },
-        {
-          # GN: //media/base/android:media_android_captureapitype
-          'target_name': 'media_android_captureapitype',
-          'type': 'none',
-          'variables': {
-            'source_file': 'capture/video/video_capture_device.h',
-          },
-          'includes': [ '../build/android/java_cpp_enum.gypi' ],
-        },
-        {
-          # GN: //media/base/android:media_android_imageformat
-          'target_name': 'media_android_imageformat',
-          'type': 'none',
-          'variables': {
-            'source_file': 'capture/video/android/video_capture_device_android.h',
-          },
-          'includes': [ '../build/android/java_cpp_enum.gypi' ],
-        },
       ],
       'conditions': [
         ['test_isolation_mode != "noop"',
diff --git a/media/media_gpu.gypi b/media/media_gpu.gypi
index 70c1398..8bea3e23 100644
--- a/media/media_gpu.gypi
+++ b/media/media_gpu.gypi
@@ -323,6 +323,7 @@
     ['OS=="win"', {
       'dependencies': [
         '../media/media.gyp:media',
+        '../media/media.gyp:mf_initializer',
         '../ui/gl/gl.gyp:gl',
         '../ui/gl/init/gl_init.gyp:gl_init',
       ],
diff --git a/media/mojo/clients/BUILD.gn b/media/mojo/clients/BUILD.gn
index a6b264c..1fc88303 100644
--- a/media/mojo/clients/BUILD.gn
+++ b/media/mojo/clients/BUILD.gn
@@ -29,10 +29,10 @@
     "mojo_decryptor.h",
     "mojo_demuxer_stream_impl.cc",
     "mojo_demuxer_stream_impl.h",
+    "mojo_renderer.cc",
+    "mojo_renderer.h",
     "mojo_renderer_factory.cc",
     "mojo_renderer_factory.h",
-    "mojo_renderer_impl.cc",
-    "mojo_renderer_impl.h",
     "mojo_video_decoder.cc",
     "mojo_video_decoder.h",
   ]
diff --git a/media/mojo/clients/mojo_renderer_impl.cc b/media/mojo/clients/mojo_renderer.cc
similarity index 77%
rename from media/mojo/clients/mojo_renderer_impl.cc
rename to media/mojo/clients/mojo_renderer.cc
index a3a0047a..94b2a57 100644
--- a/media/mojo/clients/mojo_renderer_impl.cc
+++ b/media/mojo/clients/mojo_renderer.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "media/mojo/clients/mojo_renderer_impl.h"
+#include "media/mojo/clients/mojo_renderer.h"
 
 #include <utility>
 
@@ -18,7 +18,7 @@
 
 namespace media {
 
-MojoRendererImpl::MojoRendererImpl(
+MojoRenderer::MojoRenderer(
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
     VideoRendererSink* video_renderer_sink,
@@ -31,17 +31,16 @@
   DVLOG(1) << __FUNCTION__;
 }
 
-MojoRendererImpl::~MojoRendererImpl() {
+MojoRenderer::~MojoRenderer() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
   CancelPendingCallbacks();
 }
 
-void MojoRendererImpl::Initialize(
-    DemuxerStreamProvider* demuxer_stream_provider,
-    media::RendererClient* client,
-    const PipelineStatusCB& init_cb) {
+void MojoRenderer::Initialize(DemuxerStreamProvider* demuxer_stream_provider,
+                              media::RendererClient* client,
+                              const PipelineStatusCB& init_cb) {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(demuxer_stream_provider);
@@ -70,7 +69,7 @@
     // |audio_stream_|, and the error handler can't be invoked once
     // |audio_stream_| is destroyed.
     audio_stream_->set_connection_error_handler(
-        base::Bind(&MojoRendererImpl::OnDemuxerStreamConnectionError,
+        base::Bind(&MojoRenderer::OnDemuxerStreamConnectionError,
                    base::Unretained(this), DemuxerStream::AUDIO));
   }
 
@@ -82,7 +81,7 @@
     // |video_stream_|, and the error handler can't be invoked once
     // |video_stream_| is destroyed.
     video_stream_->set_connection_error_handler(
-        base::Bind(&MojoRendererImpl::OnDemuxerStreamConnectionError,
+        base::Bind(&MojoRenderer::OnDemuxerStreamConnectionError,
                    base::Unretained(this), DemuxerStream::VIDEO));
   }
 
@@ -91,14 +90,14 @@
   // Using base::Unretained(this) is safe because |this| owns
   // |remote_renderer_|, and the callback won't be dispatched if
   // |remote_renderer_| is destroyed.
-  remote_renderer_->Initialize(binding_.CreateInterfacePtrAndBind(),
-                               std::move(audio_stream), std::move(video_stream),
-                               base::Bind(&MojoRendererImpl::OnInitialized,
-                                          base::Unretained(this), client));
+  remote_renderer_->Initialize(
+      binding_.CreateInterfacePtrAndBind(), std::move(audio_stream),
+      std::move(video_stream),
+      base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client));
 }
 
-void MojoRendererImpl::SetCdm(CdmContext* cdm_context,
-                              const CdmAttachedCB& cdm_attached_cb) {
+void MojoRenderer::SetCdm(CdmContext* cdm_context,
+                          const CdmAttachedCB& cdm_attached_cb) {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(cdm_context);
@@ -112,7 +111,7 @@
 
   int32_t cdm_id = cdm_context->GetCdmId();
   if (cdm_id == CdmContext::kInvalidCdmId) {
-    DVLOG(2) << "MojoRendererImpl only works with remote CDMs but the CDM ID "
+    DVLOG(2) << "MojoRenderer only works with remote CDMs but the CDM ID "
                 "is invalid.";
     task_runner_->PostTask(FROM_HERE, base::Bind(cdm_attached_cb, false));
     return;
@@ -121,11 +120,11 @@
   BindRemoteRendererIfNeeded();
 
   cdm_attached_cb_ = cdm_attached_cb;
-  remote_renderer_->SetCdm(cdm_id, base::Bind(&MojoRendererImpl::OnCdmAttached,
-                                              base::Unretained(this)));
+  remote_renderer_->SetCdm(
+      cdm_id, base::Bind(&MojoRenderer::OnCdmAttached, base::Unretained(this)));
 }
 
-void MojoRendererImpl::Flush(const base::Closure& flush_cb) {
+void MojoRenderer::Flush(const base::Closure& flush_cb) {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_renderer_.is_bound());
@@ -139,10 +138,10 @@
 
   flush_cb_ = flush_cb;
   remote_renderer_->Flush(
-      base::Bind(&MojoRendererImpl::OnFlushed, base::Unretained(this)));
+      base::Bind(&MojoRenderer::OnFlushed, base::Unretained(this)));
 }
 
-void MojoRendererImpl::StartPlayingFrom(base::TimeDelta time) {
+void MojoRenderer::StartPlayingFrom(base::TimeDelta time) {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_renderer_.is_bound());
@@ -155,7 +154,7 @@
   remote_renderer_->StartPlayingFrom(time.InMicroseconds());
 }
 
-void MojoRendererImpl::SetPlaybackRate(double playback_rate) {
+void MojoRenderer::SetPlaybackRate(double playback_rate) {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_renderer_.is_bound());
@@ -163,7 +162,7 @@
   remote_renderer_->SetPlaybackRate(playback_rate);
 }
 
-void MojoRendererImpl::SetVolume(float volume) {
+void MojoRenderer::SetVolume(float volume) {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_renderer_.is_bound());
@@ -171,13 +170,13 @@
   remote_renderer_->SetVolume(volume);
 }
 
-base::TimeDelta MojoRendererImpl::GetMediaTime() {
+base::TimeDelta MojoRenderer::GetMediaTime() {
   base::AutoLock auto_lock(lock_);
   DVLOG(3) << __FUNCTION__ << ": " << time_.InMilliseconds() << " ms";
   return time_;
 }
 
-bool MojoRendererImpl::HasAudio() {
+bool MojoRenderer::HasAudio() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_renderer_.is_bound());
@@ -185,7 +184,7 @@
   return !!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO);
 }
 
-bool MojoRendererImpl::HasVideo() {
+bool MojoRenderer::HasVideo() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(remote_renderer_.is_bound());
@@ -193,7 +192,7 @@
   return !!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO);
 }
 
-void MojoRendererImpl::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) {
+void MojoRenderer::OnTimeUpdate(int64_t time_usec, int64_t max_time_usec) {
   DVLOG(3) << __FUNCTION__ << ": " << time_usec << ", " << max_time_usec;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -201,19 +200,19 @@
   time_ = base::TimeDelta::FromMicroseconds(time_usec);
 }
 
-void MojoRendererImpl::OnBufferingStateChange(mojom::BufferingState state) {
+void MojoRenderer::OnBufferingStateChange(mojom::BufferingState state) {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   client_->OnBufferingStateChange(static_cast<media::BufferingState>(state));
 }
 
-void MojoRendererImpl::OnEnded() {
+void MojoRenderer::OnEnded() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   client_->OnEnded();
 }
 
-void MojoRendererImpl::OnError() {
+void MojoRenderer::OnError() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(init_cb_.is_null());
@@ -225,7 +224,7 @@
   client_->OnError(PIPELINE_ERROR_DECODE);
 }
 
-void MojoRendererImpl::OnVideoNaturalSizeChange(const gfx::Size& size) {
+void MojoRenderer::OnVideoNaturalSizeChange(const gfx::Size& size) {
   DVLOG(2) << __FUNCTION__ << ": " << size.ToString();
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -234,13 +233,13 @@
   client_->OnVideoNaturalSizeChange(size);
 }
 
-void MojoRendererImpl::OnVideoOpacityChange(bool opaque) {
+void MojoRenderer::OnVideoOpacityChange(bool opaque) {
   DVLOG(2) << __FUNCTION__ << ": " << opaque;
   DCHECK(task_runner_->BelongsToCurrentThread());
   client_->OnVideoOpacityChange(opaque);
 }
 
-void MojoRendererImpl::OnConnectionError() {
+void MojoRenderer::OnConnectionError() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -251,8 +250,7 @@
     client_->OnError(PIPELINE_ERROR_DECODE);
 }
 
-void MojoRendererImpl::OnDemuxerStreamConnectionError(
-    DemuxerStream::Type type) {
+void MojoRenderer::OnDemuxerStreamConnectionError(DemuxerStream::Type type) {
   DVLOG(1) << __FUNCTION__ << ": " << type;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -265,7 +263,7 @@
   }
 }
 
-void MojoRendererImpl::BindRemoteRendererIfNeeded() {
+void MojoRenderer::BindRemoteRendererIfNeeded() {
   DVLOG(2) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
@@ -283,11 +281,10 @@
   // |remote_renderer_|, and the error handler can't be invoked once
   // |remote_renderer_| is destroyed.
   remote_renderer_.set_connection_error_handler(
-      base::Bind(&MojoRendererImpl::OnConnectionError, base::Unretained(this)));
+      base::Bind(&MojoRenderer::OnConnectionError, base::Unretained(this)));
 }
 
-void MojoRendererImpl::OnInitialized(media::RendererClient* client,
-                                     bool success) {
+void MojoRenderer::OnInitialized(media::RendererClient* client, bool success) {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!init_cb_.is_null());
@@ -301,7 +298,7 @@
       success ? PIPELINE_OK : PIPELINE_ERROR_INITIALIZATION_FAILED);
 }
 
-void MojoRendererImpl::OnFlushed() {
+void MojoRenderer::OnFlushed() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!flush_cb_.is_null());
@@ -309,7 +306,7 @@
   base::ResetAndReturn(&flush_cb_).Run();
 }
 
-void MojoRendererImpl::OnCdmAttached(bool success) {
+void MojoRenderer::OnCdmAttached(bool success) {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(!cdm_attached_cb_.is_null());
@@ -317,7 +314,7 @@
   base::ResetAndReturn(&cdm_attached_cb_).Run(success);
 }
 
-void MojoRendererImpl::CancelPendingCallbacks() {
+void MojoRenderer::CancelPendingCallbacks() {
   DVLOG(1) << __FUNCTION__;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
diff --git a/media/mojo/clients/mojo_renderer_impl.h b/media/mojo/clients/mojo_renderer.h
similarity index 87%
rename from media/mojo/clients/mojo_renderer_impl.h
rename to media/mojo/clients/mojo_renderer.h
index f37733c..44cad75 100644
--- a/media/mojo/clients/mojo_renderer_impl.h
+++ b/media/mojo/clients/mojo_renderer.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef MEDIA_MOJO_CLIENTS_MOJO_RENDERER_IMPL_H_
-#define MEDIA_MOJO_CLIENTS_MOJO_RENDERER_IMPL_H_
+#ifndef MEDIA_MOJO_CLIENTS_MOJO_RENDERER_H_
+#define MEDIA_MOJO_CLIENTS_MOJO_RENDERER_H_
 
 #include <stdint.h>
 
@@ -25,7 +25,7 @@
 class VideoRendererSink;
 
 // A media::Renderer that proxies to a mojom::Renderer. That
-// mojom::Renderer proxies back to the MojoRendererImpl via the
+// mojom::Renderer proxies back to the MojoRenderer via the
 // mojom::RendererClient interface.
 //
 // This class can be created on any thread, where the |remote_renderer| is
@@ -34,14 +34,13 @@
 // |task_runner|*. That means all Renderer and RendererClient methods will be
 // called/dispached on the |task_runner|. The only exception is GetMediaTime(),
 // which can be called on any thread.
-class MojoRendererImpl : public Renderer, public mojom::RendererClient {
+class MojoRenderer : public Renderer, public mojom::RendererClient {
  public:
-  MojoRendererImpl(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
-      std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
-      VideoRendererSink* video_renderer_sink,
-      mojom::RendererPtr remote_renderer);
-  ~MojoRendererImpl() override;
+  MojoRenderer(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
+               std::unique_ptr<VideoOverlayFactory> video_overlay_factory,
+               VideoRendererSink* video_renderer_sink,
+               mojom::RendererPtr remote_renderer);
+  ~MojoRenderer() override;
 
   // Renderer implementation.
   void Initialize(DemuxerStreamProvider* demuxer_stream_provider,
@@ -105,7 +104,7 @@
   media::RendererClient* client_ = nullptr;
 
   // Mojo demuxer streams.
-  // Owned by MojoRendererImpl instead of remote mojom::Renderer
+  // Owned by MojoRenderer instead of remote mojom::Renderer
   // becuase these demuxer streams need to be destroyed as soon as |this| is
   // destroyed. The local demuxer streams returned by DemuxerStreamProvider
   // cannot be used after |this| is destroyed.
@@ -134,9 +133,9 @@
   mutable base::Lock lock_;
   base::TimeDelta time_;
 
-  DISALLOW_COPY_AND_ASSIGN(MojoRendererImpl);
+  DISALLOW_COPY_AND_ASSIGN(MojoRenderer);
 };
 
 }  // namespace media
 
-#endif  // MEDIA_MOJO_CLIENTS_MOJO_RENDERER_IMPL_H_
+#endif  // MEDIA_MOJO_CLIENTS_MOJO_RENDERER_H_
diff --git a/media/mojo/clients/mojo_renderer_factory.cc b/media/mojo/clients/mojo_renderer_factory.cc
index c86e19f4..750b514 100644
--- a/media/mojo/clients/mojo_renderer_factory.cc
+++ b/media/mojo/clients/mojo_renderer_factory.cc
@@ -5,7 +5,7 @@
 #include "media/mojo/clients/mojo_renderer_factory.h"
 
 #include "base/single_thread_task_runner.h"
-#include "media/mojo/clients/mojo_renderer_impl.h"
+#include "media/mojo/clients/mojo_renderer.h"
 #include "media/renderers/video_overlay_factory.h"
 #include "services/shell/public/cpp/connect.h"
 #include "services/shell/public/interfaces/interface_provider.mojom.h"
@@ -36,8 +36,8 @@
   shell::GetInterface<mojom::Renderer>(interface_provider_, &renderer_ptr);
 
   return std::unique_ptr<Renderer>(
-      new MojoRendererImpl(media_task_runner, std::move(overlay_factory),
-                           video_renderer_sink, std::move(renderer_ptr)));
+      new MojoRenderer(media_task_runner, std::move(overlay_factory),
+                       video_renderer_sink, std::move(renderer_ptr)));
 }
 
 }  // namespace media
diff --git a/media/mojo/clients/mojo_renderer_factory.h b/media/mojo/clients/mojo_renderer_factory.h
index 2937666..2a1ae30 100644
--- a/media/mojo/clients/mojo_renderer_factory.h
+++ b/media/mojo/clients/mojo_renderer_factory.h
@@ -21,7 +21,7 @@
 
 class GpuVideoAcceleratorFactories;
 
-// The default factory class for creating MojoRendererImpl.
+// The default factory class for creating MojoRenderer.
 class MojoRendererFactory : public RendererFactory {
  public:
   using GetGpuFactoriesCB = base::Callback<GpuVideoAcceleratorFactories*()>;
diff --git a/media/mojo/clients/mojo_renderer_unittest.cc b/media/mojo/clients/mojo_renderer_unittest.cc
index 8f90d33..75cf5e0 100644
--- a/media/mojo/clients/mojo_renderer_unittest.cc
+++ b/media/mojo/clients/mojo_renderer_unittest.cc
@@ -15,7 +15,7 @@
 #include "media/base/mock_filters.h"
 #include "media/base/test_helpers.h"
 #include "media/cdm/default_cdm_factory.h"
-#include "media/mojo/clients/mojo_renderer_impl.h"
+#include "media/mojo/clients/mojo_renderer.h"
 #include "media/mojo/common/media_type_converters.h"
 #include "media/mojo/interfaces/content_decryption_module.mojom.h"
 #include "media/mojo/interfaces/renderer.mojom.h"
@@ -55,9 +55,9 @@
         mojo::GetProxy(&remote_renderer));
 
     mojo_renderer_.reset(
-        new MojoRendererImpl(message_loop_.task_runner(),
-                             std::unique_ptr<VideoOverlayFactory>(nullptr),
-                             nullptr, std::move(remote_renderer)));
+        new MojoRenderer(message_loop_.task_runner(),
+                         std::unique_ptr<VideoOverlayFactory>(nullptr), nullptr,
+                         std::move(remote_renderer)));
 
     // CreateAudioStream() and CreateVideoStream() overrides expectations for
     // expected non-NULL streams.
@@ -178,8 +178,8 @@
   // Fixture members.
   base::MessageLoop message_loop_;
 
-  // The MojoRendererImpl that we are testing.
-  std::unique_ptr<MojoRendererImpl> mojo_renderer_;
+  // The MojoRenderer that we are testing.
+  std::unique_ptr<MojoRenderer> mojo_renderer_;
 
   // Client side mocks and helpers.
   StrictMock<MockRendererClient> renderer_client_;
diff --git a/media/test/pipeline_integration_test.cc b/media/test/pipeline_integration_test.cc
index 416a8559..799fc85 100644
--- a/media/test/pipeline_integration_test.cc
+++ b/media/test/pipeline_integration_test.cc
@@ -38,7 +38,7 @@
 #include "url/gurl.h"
 
 #if defined(MOJO_RENDERER)
-#include "media/mojo/clients/mojo_renderer_impl.h"
+#include "media/mojo/clients/mojo_renderer.h"
 #include "media/mojo/interfaces/renderer.mojom.h"
 #include "media/mojo/interfaces/service_factory.mojom.h"
 #include "services/shell/public/cpp/connect.h"
@@ -712,8 +712,8 @@
     mojom::RendererPtr mojo_renderer;
     media_service_factory_->CreateRenderer(mojo::GetProxy(&mojo_renderer));
 
-    return base::WrapUnique(new MojoRendererImpl(message_loop_.task_runner(),
-                                                 std::move(mojo_renderer)));
+    return base::WrapUnique(new MojoRenderer(message_loop_.task_runner(),
+                                             std::move(mojo_renderer)));
   }
 
  private:
diff --git a/mojo/message_pump/handle_watcher.cc b/mojo/message_pump/handle_watcher.cc
index 9bdbb2a..7f6f5616 100644
--- a/mojo/message_pump/handle_watcher.cc
+++ b/mojo/message_pump/handle_watcher.cc
@@ -277,7 +277,7 @@
 }
 
 void WatcherThreadManager::ProcessRequestsOnBackendThread() {
-  DCHECK_EQ(thread_.message_loop(), base::MessageLoop::current());
+  DCHECK(thread_.task_runner()->BelongsToCurrentThread());
 
   Requests requests;
   {
diff --git a/net/BUILD.gn b/net/BUILD.gn
index 2ec0189..b3609288 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -68,6 +68,9 @@
   if (disable_ftp_support) {
     defines += [ "DISABLE_FTP_SUPPORT=1" ]
   }
+  if (enable_websockets) {
+    defines += [ "ENABLE_WEBSOCKETS" ]
+  }
 }
 
 config("net_internal_config") {
diff --git a/net/cert/internal/cert_issuer_source_aia.cc b/net/cert/internal/cert_issuer_source_aia.cc
index d948a33c..4dacc340 100644
--- a/net/cert/internal/cert_issuer_source_aia.cc
+++ b/net/cert/internal/cert_issuer_source_aia.cc
@@ -89,7 +89,7 @@
     // bytes.
     if (!ParsedCertificate::CreateAndAddToVector(
             fetched_bytes.data(), fetched_bytes.size(),
-            ParsedCertificate::DataSource::INTERNAL_COPY, &results_)) {
+            ParsedCertificate::DataSource::INTERNAL_COPY, {}, &results_)) {
       // TODO(mattm): propagate error info.
       LOG(ERROR) << "Error parsing AIA data";
     }
diff --git a/net/cert/internal/cert_issuer_source_aia_unittest.cc b/net/cert/internal/cert_issuer_source_aia_unittest.cc
index 31b2577..455cf66 100644
--- a/net/cert/internal/cert_issuer_source_aia_unittest.cc
+++ b/net/cert/internal/cert_issuer_source_aia_unittest.cc
@@ -38,7 +38,7 @@
                   "CERTIFICATE", &der);
   if (!r)
     return r;
-  *result = ParsedCertificate::CreateFromCertificateCopy(der);
+  *result = ParsedCertificate::CreateFromCertificateCopy(der, {});
   if (!*result)
     return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed";
   return ::testing::AssertionSuccess();
diff --git a/net/cert/internal/cert_issuer_source_static_unittest.cc b/net/cert/internal/cert_issuer_source_static_unittest.cc
index 09dc015..148f362 100644
--- a/net/cert/internal/cert_issuer_source_static_unittest.cc
+++ b/net/cert/internal/cert_issuer_source_static_unittest.cc
@@ -36,7 +36,7 @@
                   "CERTIFICATE", &der);
   if (!r)
     return r;
-  *result = ParsedCertificate::CreateFromCertificateCopy(der);
+  *result = ParsedCertificate::CreateFromCertificateCopy(der, {});
   if (!*result)
     return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed";
   return ::testing::AssertionSuccess();
diff --git a/net/cert/internal/parse_certificate.cc b/net/cert/internal/parse_certificate.cc
index d9413b3..644734c 100644
--- a/net/cert/internal/parse_certificate.cc
+++ b/net/cert/internal/parse_certificate.cc
@@ -219,7 +219,9 @@
 //        extensions      [3]  EXPLICIT Extensions OPTIONAL
 //                             -- If present, version MUST be v3
 //        }
-bool ParseTbsCertificate(const der::Input& tbs_tlv, ParsedTbsCertificate* out) {
+bool ParseTbsCertificate(const der::Input& tbs_tlv,
+                         const ParseCertificateOptions& options,
+                         ParsedTbsCertificate* out) {
   der::Parser parser(tbs_tlv);
 
   //   Certificate  ::=  SEQUENCE  {
@@ -249,8 +251,10 @@
   //        serialNumber         CertificateSerialNumber,
   if (!tbs_parser.ReadTag(der::kInteger, &out->serial_number))
     return false;
-  if (!VerifySerialNumber(out->serial_number))
+  if (!options.allow_invalid_serial_numbers &&
+      !VerifySerialNumber(out->serial_number)) {
     return false;
+  }
 
   //        signature            AlgorithmIdentifier,
   if (!ReadSequenceTLV(&tbs_parser, &out->signature_algorithm_tlv))
diff --git a/net/cert/internal/parse_certificate.h b/net/cert/internal/parse_certificate.h
index 6fde448..13409dc 100644
--- a/net/cert/internal/parse_certificate.h
+++ b/net/cert/internal/parse_certificate.h
@@ -46,6 +46,14 @@
 //     gracefully handle such certificates.
 NET_EXPORT bool VerifySerialNumber(const der::Input& value) WARN_UNUSED_RESULT;
 
+struct NET_EXPORT ParseCertificateOptions {
+  // If set to true, then parsing will skip checks on the certificate's serial
+  // number. The only requirement will be that the serial number is an INTEGER,
+  // however it is not required to be a valid DER-encoding (i.e. minimal
+  // encoding), nor is it required to be constrained to any particular length.
+  bool allow_invalid_serial_numbers = false;
+};
+
 // Parses a DER-encoded "Certificate" as specified by RFC 5280. Returns true on
 // success and sets the results in the |out_*| parameters.
 //
@@ -87,7 +95,8 @@
     WARN_UNUSED_RESULT;
 
 // Parses a DER-encoded "TBSCertificate" as specified by RFC 5280. Returns true
-// on success and sets the results in |out|.
+// on success and sets the results in |out|. Certain invalid inputs may
+// be accepted based on the provided |options|.
 //
 // Note that on success |out| aliases data from the input |tbs_tlv|.
 // Hence the fields of the ParsedTbsCertificate are only valid as long as
@@ -115,6 +124,7 @@
 //                                 -- If present, version MUST be v3
 //            }
 NET_EXPORT bool ParseTbsCertificate(const der::Input& tbs_tlv,
+                                    const ParseCertificateOptions& options,
                                     ParsedTbsCertificate* out)
     WARN_UNUSED_RESULT;
 
@@ -149,7 +159,13 @@
   // instance if the serial number was 1000 then this would contain bytes
   // {0x03, 0xE8}.
   //
-  // In addition to being a valid DER-encoded INTEGER, parsing guarantees that
+  // The serial number may or may not be a valid DER-encoded INTEGER:
+  //
+  // If the option |allow_invalid_serial_numbers=true| was used during
+  // parsing, then nothing further can be assumed about these bytes.
+  //
+  // Otherwise if |allow_invalid_serial_numbers=false| then in addition
+  // to being a valid DER-encoded INTEGER, parsing guarantees that
   // the serial number is at most 20 bytes long. Parsing does NOT guarantee
   // that the integer is positive (might be zero or negative).
   der::Input serial_number;
diff --git a/net/cert/internal/parse_certificate_fuzzer.cc b/net/cert/internal/parse_certificate_fuzzer.cc
index e564c9b..5efcd6f 100644
--- a/net/cert/internal/parse_certificate_fuzzer.cc
+++ b/net/cert/internal/parse_certificate_fuzzer.cc
@@ -39,10 +39,9 @@
       SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv));
 
   ParsedTbsCertificate tbs;
-  if (!ParseTbsCertificate(tbs_certificate_tlv, &tbs))
+  if (!ParseTbsCertificate(tbs_certificate_tlv, {}, &tbs))
     return;
 
-  ignore_result(VerifySerialNumber(tbs.serial_number));
   RDNSequence subject;
   ignore_result(ParseName(tbs.subject_tlv, &subject));
 
diff --git a/net/cert/internal/parse_certificate_unittest.cc b/net/cert/internal/parse_certificate_unittest.cc
index e3a90eed..474ab6d2 100644
--- a/net/cert/internal/parse_certificate_unittest.cc
+++ b/net/cert/internal/parse_certificate_unittest.cc
@@ -156,7 +156,7 @@
 
   // Parsing the TBSCertificate should succeed.
   ParsedTbsCertificate parsed;
-  ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), &parsed));
+  ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), {}, &parsed));
 
   // Ensure that the ParsedTbsCertificate matches expectations.
   EXPECT_EQ(expected_version, parsed.version);
@@ -199,7 +199,7 @@
 
   // Parsing the TBSCertificate should fail.
   ParsedTbsCertificate parsed;
-  ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), &parsed));
+  ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), {}, &parsed));
 }
 
 // Tests parsing a TBSCertificate for v3 that contains no optional fields.
diff --git a/net/cert/internal/parse_ocsp.cc b/net/cert/internal/parse_ocsp.cc
index 87b9d6c4..0243d95 100644
--- a/net/cert/internal/parse_ocsp.cc
+++ b/net/cert/internal/parse_ocsp.cc
@@ -499,10 +499,10 @@
   out->status = OCSPCertStatus::Status::GOOD;
 
   ParsedTbsCertificate tbs_cert;
-  if (!ParseTbsCertificate(cert_tbs_certificate_tlv, &tbs_cert))
+  if (!ParseTbsCertificate(cert_tbs_certificate_tlv, {}, &tbs_cert))
     return false;
   ParsedTbsCertificate issuer_tbs_cert;
-  if (!ParseTbsCertificate(issuer_tbs_certificate_tlv, &issuer_tbs_cert))
+  if (!ParseTbsCertificate(issuer_tbs_certificate_tlv, {}, &issuer_tbs_cert))
     return false;
 
   bool found = false;
diff --git a/net/cert/internal/parsed_certificate.cc b/net/cert/internal/parsed_certificate.cc
index 8ea860f3..e8e08c4e 100644
--- a/net/cert/internal/parsed_certificate.cc
+++ b/net/cert/internal/parsed_certificate.cc
@@ -27,7 +27,8 @@
 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateData(
     const uint8_t* data,
     size_t length,
-    DataSource source) {
+    DataSource source,
+    const ParseCertificateOptions& options) {
   scoped_refptr<ParsedCertificate> result(new ParsedCertificate);
 
   switch (source) {
@@ -47,8 +48,10 @@
     return nullptr;
   }
 
-  if (!ParseTbsCertificate(result->tbs_certificate_tlv_, &result->tbs_))
+  if (!ParseTbsCertificate(result->tbs_certificate_tlv_, options,
+                           &result->tbs_)) {
     return nullptr;
+  }
 
   // Attempt to parse the signature algorithm contained in the Certificate.
   // Do not give up on failure here, since SignatureAlgorithm::CreateFromDer
@@ -147,19 +150,21 @@
 }
 
 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateCopy(
-    const base::StringPiece& data) {
+    const base::StringPiece& data,
+    const ParseCertificateOptions& options) {
   return ParsedCertificate::CreateFromCertificateData(
       reinterpret_cast<const uint8_t*>(data.data()), data.size(),
-      DataSource::INTERNAL_COPY);
+      DataSource::INTERNAL_COPY, options);
 }
 
 bool ParsedCertificate::CreateAndAddToVector(
     const uint8_t* data,
     size_t length,
     DataSource source,
+    const ParseCertificateOptions& options,
     std::vector<scoped_refptr<ParsedCertificate>>* chain) {
   scoped_refptr<ParsedCertificate> cert(
-      CreateFromCertificateData(data, length, source));
+      CreateFromCertificateData(data, length, source, options));
   if (!cert)
     return false;
   chain->push_back(std::move(cert));
diff --git a/net/cert/internal/parsed_certificate.h b/net/cert/internal/parsed_certificate.h
index 0f960e2a..8237752 100644
--- a/net/cert/internal/parsed_certificate.h
+++ b/net/cert/internal/parsed_certificate.h
@@ -50,7 +50,8 @@
   static scoped_refptr<ParsedCertificate> CreateFromCertificateData(
       const uint8_t* data,
       size_t length,
-      DataSource source);
+      DataSource source,
+      const ParseCertificateOptions& options);
 
   // Creates a ParsedCertificate and appends it to |chain|. Returns true if the
   // certificate was successfully parsed and added. If false is return, |chain|
@@ -59,11 +60,13 @@
       const uint8_t* data,
       size_t length,
       DataSource source,
+      const ParseCertificateOptions& options,
       std::vector<scoped_refptr<net::ParsedCertificate>>* chain);
 
   // Creates a ParsedCertificate, copying the data from |data|.
   static scoped_refptr<ParsedCertificate> CreateFromCertificateCopy(
-      const base::StringPiece& data);
+      const base::StringPiece& data,
+      const ParseCertificateOptions& options);
 
   // Returns the DER-encoded certificate data for this cert.
   const der::Input& der_cert() const { return cert_; }
diff --git a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
index 6925f64..4c543f4 100644
--- a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
+++ b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
@@ -55,7 +55,7 @@
     // First entry in the PKITS chain is the trust anchor.
     TrustStore trust_store;
     scoped_refptr<ParsedCertificate> anchor(
-        ParsedCertificate::CreateFromCertificateCopy(cert_ders[0]));
+        ParsedCertificate::CreateFromCertificateCopy(cert_ders[0], {}));
     EXPECT_TRUE(anchor);
     if (anchor)
       trust_store.AddTrustedCertificate(std::move(anchor));
@@ -67,7 +67,7 @@
       if (!net::ParsedCertificate::CreateAndAddToVector(
               reinterpret_cast<const uint8_t*>(cert_ders[i].data()),
               cert_ders[i].size(),
-              net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE,
+              net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {},
               &input_chain)) {
         ADD_FAILURE() << "cert " << i << " failed to parse";
         return false;
diff --git a/net/cert/internal/verify_certificate_chain_unittest.cc b/net/cert/internal/verify_certificate_chain_unittest.cc
index 4cd03c0..9103f12f 100644
--- a/net/cert/internal/verify_certificate_chain_unittest.cc
+++ b/net/cert/internal/verify_certificate_chain_unittest.cc
@@ -77,7 +77,7 @@
       chain->push_back(block_data);
     } else if (block_type == kTrustedCertificateHeader) {
       scoped_refptr<ParsedCertificate> cert(
-          ParsedCertificate::CreateFromCertificateCopy(block_data));
+          ParsedCertificate::CreateFromCertificateCopy(block_data, {}));
       ASSERT_TRUE(cert);
       trust_store->AddTrustedCertificate(std::move(cert));
     } else if (block_type == kTimeHeader) {
@@ -109,7 +109,8 @@
   for (const auto& cert_der : chain) {
     ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector(
         reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size(),
-        net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, &input_chain));
+        net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {},
+        &input_chain));
   }
 
   SimpleSignaturePolicy signature_policy(1024);
diff --git a/net/disk_cache/entry_unittest.cc b/net/disk_cache/entry_unittest.cc
index e9c701dc..8f35755 100644
--- a/net/disk_cache/entry_unittest.cc
+++ b/net/disk_cache/entry_unittest.cc
@@ -602,7 +602,7 @@
   ExternalAsyncIO();
 }
 
-// TODO(ios): This test is flaky. http://crbug.com/497101
+// TODO(http://crbug.com/497101): This test is flaky.
 #if defined(OS_IOS)
 #define MAYBE_ExternalAsyncIONoBuffer DISABLED_ExternalAsyncIONoBuffer
 #else
diff --git a/net/net.gyp b/net/net.gyp
index 5fc0f37..acd2a85 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -277,6 +277,9 @@
             'sources': [
               '<@(net_websockets_test_sources)',
             ],
+            'defines': [
+              'ENABLE_WEBSOCKETS',
+            ],
             'dependencies': [
               'http_server',
             ],
diff --git a/net/net_common.gypi b/net/net_common.gypi
index 47c86fc..9f91244 100644
--- a/net/net_common.gypi
+++ b/net/net_common.gypi
@@ -212,6 +212,7 @@
         ],
     }],
     [ 'enable_websockets == 1', {
+        'defines': ['ENABLE_WEBSOCKETS'],
         'sources': ['<@(net_websockets_sources)']
     }],
     [ 'enable_mdns != 1', {
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index 978fae63..134bf45 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -648,14 +648,12 @@
     {"http://upgrade.test:123/", true, "https://upgrade.test:123/"},
     {"http://no-upgrade.test/", false, "http://no-upgrade.test/"},
     {"http://no-upgrade.test:123/", false, "http://no-upgrade.test:123/"},
-// iOS doesn't support websockets; see the comments above
-// URLRequestHttpJobWebSocketTest for detail.
-#if !defined(OS_IOS)
+#if defined(ENABLE_WEBSOCKETS)
     {"ws://upgrade.test/", true, "wss://upgrade.test/"},
     {"ws://upgrade.test:123/", true, "wss://upgrade.test:123/"},
     {"ws://no-upgrade.test/", false, "ws://no-upgrade.test/"},
     {"ws://no-upgrade.test:123/", false, "ws://no-upgrade.test:123/"},
-#endif  // !defined(OS_IOS)
+#endif  // defined(ENABLE_WEBSOCKETS)
   };
 
   for (const auto& test : cases) {
@@ -896,11 +894,7 @@
                                              bool));
 };
 
-// iOS doesn't support WebSockets, so these tests fail with ERR_UNKOWN_SCHEME on
-// iOS.
-// TODO(mmenke):  Hard coding features based on OS is regression prone and ugly.
-// Seems like this should use a build flag instead.
-#if !defined(OS_IOS)
+#if defined(ENABLE_WEBSOCKETS)
 
 class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
  public:
@@ -1009,7 +1003,7 @@
   EXPECT_TRUE(fake_handshake_stream->initialize_stream_was_called());
 }
 
-#endif  // !defined(OS_IOS)
+#endif  // defined(ENABLE_WEBSOCKETS)
 
 }  // namespace
 
diff --git a/net/url_request/url_request_job_manager.cc b/net/url_request/url_request_job_manager.cc
index 092708f..15790a7 100644
--- a/net/url_request/url_request_job_manager.cc
+++ b/net/url_request/url_request_job_manager.cc
@@ -30,13 +30,13 @@
 }  // namespace
 
 static const SchemeToFactory kBuiltinFactories[] = {
-  { "http", URLRequestHttpJob::Factory },
-  { "https", URLRequestHttpJob::Factory },
+    {"http", URLRequestHttpJob::Factory},
+    {"https", URLRequestHttpJob::Factory},
 
-#if !defined(OS_IOS)
-  { "ws", URLRequestHttpJob::Factory },
-  { "wss", URLRequestHttpJob::Factory },
-#endif  // !defined(OS_IOS)
+#if defined(ENABLE_WEBSOCKETS)
+    {"ws", URLRequestHttpJob::Factory},
+    {"wss", URLRequestHttpJob::Factory},
+#endif  // defined(ENABLE_WEBSOCKETS)
 };
 
 // static
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn
index 2ea13a8..a0339f7 100644
--- a/remoting/host/BUILD.gn
+++ b/remoting/host/BUILD.gn
@@ -1144,33 +1144,36 @@
   }
 
   if (is_win && is_chrome_branded) {
+    # We do not release a 64 bits binary. So to avoid any potential
+    # misunderstanding, we only build 32 bits MSI file.
     if (target_cpu == "x86") {
       # The script uses "ia32" instead of "x86".
       msi_script_arch = "ia32"
-    } else {
-      msi_script_arch = target_cpu
-    }
 
-    # GYP version: remoting/remoting_host_win.gyp:remoting_host_installation
-    action("remoting_host_installation") {
-      deps = [
-        "//remoting/host:remoting_me2me_host_archive",
-      ]
-      script = "../tools/zip2msi.py"
-      outputs = [
-        "$root_out_dir/chromoting.msi",
-      ]
-      args = [
-        "--wix_path",
-        rebase_path("//third_party/wix"),
-        "--intermediate_dir",
-        rebase_path("$root_gen_dir/installation", root_build_dir),
-        "--target_arch",
-        msi_script_arch,
-        rebase_path("$root_out_dir/remoting-me2me-host-$current_os.zip",
-                    root_build_dir),
-        rebase_path(outputs[0], root_build_dir),
-      ]
+      # GYP version: remoting/remoting_host_win.gyp:remoting_host_installation
+      action("remoting_host_installation") {
+        deps = [
+          "//remoting/host:remoting_me2me_host_archive",
+        ]
+        script = "../tools/zip2msi.py"
+        outputs = [
+          "$root_out_dir/chromoting.msi",
+        ]
+        args = [
+          "--wix_path",
+          rebase_path("//third_party/wix"),
+          "--intermediate_dir",
+          rebase_path("$root_gen_dir/installation", root_build_dir),
+          "--target_arch",
+          msi_script_arch,
+          rebase_path("$root_out_dir/remoting-me2me-host-$current_os.zip",
+                      root_build_dir),
+          rebase_path(outputs[0], root_build_dir),
+        ]
+      }
+    } else {
+      group("remoting_host_installation") {
+      }
     }
   }
 }
diff --git a/remoting/remoting_host_win.gypi b/remoting/remoting_host_win.gypi
index f998e05b..475f603 100644
--- a/remoting/remoting_host_win.gypi
+++ b/remoting/remoting_host_win.gypi
@@ -563,7 +563,9 @@
     # component build is used the produced installation will not work due to
     # missing DLLs. We build it anyway to make sure the GYP scripts are executed
     # by the bots.
-    ['wix_exists == "True"', {
+    # We do not release a 64 bits binary. So to avoid any potential
+    # misunderstanding, we only build 32 bits MSI file.
+    ['wix_exists == "True" and target_arch == "ia32"', {
       'targets': [
         {
           'target_name': 'remoting_host_installation',
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 561e42d..8da1ca3 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -238,6 +238,10 @@
 #   define SK_SUPPORT_LEGACY_COMPUTESAVELAYER_FLAG
 #endif
 
+#ifndef    SK_SUPPORT_LEGACY_COLORPROFILETYPE
+#   define SK_SUPPORT_LEGACY_COLORPROFILETYPE
+#endif
+
 ///////////////////////// Imported from BUILD.gn and skia_common.gypi
 
 /* In some places Skia can use static initializers for global initialization,
diff --git a/sync/internal_api/http_bridge.cc b/sync/internal_api/http_bridge.cc
index 24e8413..87884c55 100644
--- a/sync/internal_api/http_bridge.cc
+++ b/sync/internal_api/http_bridge.cc
@@ -11,7 +11,6 @@
 
 #include "base/bit_cast.h"
 #include "base/location.h"
-#include "base/message_loop/message_loop.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/single_thread_task_runner.h"
@@ -131,8 +130,7 @@
     const scoped_refptr<net::URLRequestContextGetter>& context_getter,
     const NetworkTimeUpdateCallback& network_time_update_callback,
     const BindToTrackerCallback& bind_to_tracker_callback)
-    : created_on_loop_(base::MessageLoop::current()),
-      user_agent_(user_agent),
+    : user_agent_(user_agent),
       http_post_completed_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                            base::WaitableEvent::InitialState::NOT_SIGNALED),
       request_context_getter_(context_getter),
@@ -151,7 +149,7 @@
 
 void HttpBridge::SetURL(const char* url, int port) {
 #if DCHECK_IS_ON()
-  DCHECK_EQ(base::MessageLoop::current(), created_on_loop_);
+  DCHECK(thread_checker_.CalledOnValidThread());
   {
     base::AutoLock lock(fetch_state_lock_);
     DCHECK(!fetch_state_.request_completed);
@@ -170,7 +168,7 @@
                                 int content_length,
                                 const char* content) {
 #if DCHECK_IS_ON()
-  DCHECK_EQ(base::MessageLoop::current(), created_on_loop_);
+  DCHECK(thread_checker_.CalledOnValidThread());
   {
     base::AutoLock lock(fetch_state_lock_);
     DCHECK(!fetch_state_.request_completed);
@@ -191,7 +189,7 @@
 
 bool HttpBridge::MakeSynchronousPost(int* error_code, int* response_code) {
 #if DCHECK_IS_ON()
-  DCHECK_EQ(base::MessageLoop::current(), created_on_loop_);
+  DCHECK(thread_checker_.CalledOnValidThread());
   {
     base::AutoLock lock(fetch_state_lock_);
     DCHECK(!fetch_state_.request_completed);
@@ -260,14 +258,14 @@
 }
 
 int HttpBridge::GetResponseContentLength() const {
-  DCHECK_EQ(base::MessageLoop::current(), created_on_loop_);
+  DCHECK(thread_checker_.CalledOnValidThread());
   base::AutoLock lock(fetch_state_lock_);
   DCHECK(fetch_state_.request_completed);
   return fetch_state_.response_content.size();
 }
 
 const char* HttpBridge::GetResponseContent() const {
-  DCHECK_EQ(base::MessageLoop::current(), created_on_loop_);
+  DCHECK(thread_checker_.CalledOnValidThread());
   base::AutoLock lock(fetch_state_lock_);
   DCHECK(fetch_state_.request_completed);
   return fetch_state_.response_content.data();
@@ -275,8 +273,7 @@
 
 const std::string HttpBridge::GetResponseHeaderValue(
     const std::string& name) const {
-
-  DCHECK_EQ(base::MessageLoop::current(), created_on_loop_);
+  DCHECK(thread_checker_.CalledOnValidThread());
   base::AutoLock lock(fetch_state_lock_);
   DCHECK(fetch_state_.request_completed);
 
diff --git a/sync/internal_api/http_bridge_unittest.cc b/sync/internal_api/http_bridge_unittest.cc
index 78870a3..74337fc 100644
--- a/sync/internal_api/http_bridge_unittest.cc
+++ b/sync/internal_api/http_bridge_unittest.cc
@@ -6,6 +6,7 @@
 #include <stdint.h>
 
 #include "base/bit_cast.h"
+#include "base/single_thread_task_runner.h"
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread.h"
@@ -142,7 +143,8 @@
 
  protected:
   void MakeAsynchronousPost() override {
-    ASSERT_TRUE(base::MessageLoop::current() == test_->GetIOThreadLoop());
+    ASSERT_TRUE(
+        test_->GetIOThreadLoop()->task_runner()->BelongsToCurrentThread());
     if (never_finishes_)
       return;
 
@@ -156,7 +158,8 @@
   ~ShuntedHttpBridge() override {}
 
   void CallOnURLFetchComplete() {
-    ASSERT_TRUE(base::MessageLoop::current() == test_->GetIOThreadLoop());
+    ASSERT_TRUE(
+        test_->GetIOThreadLoop()->task_runner()->BelongsToCurrentThread());
     // We return a dummy content response.
     std::string response_content = "success!";
     net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL);
diff --git a/sync/internal_api/public/engine/model_safe_worker.cc b/sync/internal_api/public/engine/model_safe_worker.cc
index 3c96a27..8031955 100644
--- a/sync/internal_api/public/engine/model_safe_worker.cc
+++ b/sync/internal_api/public/engine/model_safe_worker.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/json/json_writer.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 
 namespace syncer {
@@ -76,8 +77,7 @@
     : stopped_(false),
       work_done_or_stopped_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                             base::WaitableEvent::InitialState::NOT_SIGNALED),
-      observer_(observer),
-      working_loop_(NULL) {}
+      observer_(observer) {}
 
 ModelSafeWorker::~ModelSafeWorker() {}
 
@@ -125,8 +125,8 @@
   }
 
   {
-    base::AutoLock l(working_loop_lock_);
-    working_loop_ = NULL;
+    base::AutoLock l(working_task_runner_lock_);
+    working_task_runner_ = NULL;
   }
 
   if (observer_)
@@ -137,13 +137,13 @@
   base::Callback<void(ModelSafeGroup)> unregister_done_callback;
 
   {
-    base::AutoLock l(working_loop_lock_);
-    DCHECK(!working_loop_);
+    base::AutoLock l(working_task_runner_lock_);
+    DCHECK(!working_task_runner_);
 
     if (unregister_done_callback_.is_null()) {
       // Expected case - UnregisterForLoopDestruction hasn't been called yet.
       base::MessageLoop::current()->AddDestructionObserver(this);
-      working_loop_ = base::MessageLoop::current();
+      working_task_runner_ = base::ThreadTaskRunnerHandle::Get();
     } else {
       // Rare case which is possible when the model type thread remains
       // blocked for the entire session and UnregisterForLoopDestruction ends
@@ -165,16 +165,15 @@
 
 void ModelSafeWorker::UnregisterForLoopDestruction(
     base::Callback<void(ModelSafeGroup)> unregister_done_callback) {
-  base::AutoLock l(working_loop_lock_);
-  if (working_loop_ != NULL) {
+  base::AutoLock l(working_task_runner_lock_);
+  if (working_task_runner_) {
     // Normal case - observer registration has been already done.
     // Delegate to the sync thread to do the actual unregistration in
     // UnregisterForLoopDestructionAsync.
-    DCHECK_NE(base::MessageLoop::current(), working_loop_);
-    working_loop_->PostTask(
+    DCHECK(!working_task_runner_->BelongsToCurrentThread());
+    working_task_runner_->PostTask(
         FROM_HERE,
-        base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync,
-                   this,
+        base::Bind(&ModelSafeWorker::UnregisterForLoopDestructionAsync, this,
                    unregister_done_callback));
   } else {
     // The working loop is still unknown, probably because the model type
@@ -187,10 +186,10 @@
 void ModelSafeWorker::UnregisterForLoopDestructionAsync(
     base::Callback<void(ModelSafeGroup)> unregister_done_callback) {
   {
-    base::AutoLock l(working_loop_lock_);
-    if (!working_loop_)
+    base::AutoLock l(working_task_runner_lock_);
+    if (!working_task_runner_)
       return;
-    DCHECK_EQ(base::MessageLoop::current(), working_loop_);
+    DCHECK(working_task_runner_->BelongsToCurrentThread());
   }
 
   DCHECK(stopped_);
diff --git a/sync/internal_api/public/engine/model_safe_worker.h b/sync/internal_api/public/engine/model_safe_worker.h
index 1e016a4..87662db8 100644
--- a/sync/internal_api/public/engine/model_safe_worker.h
+++ b/sync/internal_api/public/engine/model_safe_worker.h
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
+#include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
 #include "sync/base/sync_export.h"
@@ -135,11 +136,11 @@
 
   // Remember working loop for posting task to unregister destruction
   // observation from sync thread when shutting down sync.
-  base::Lock working_loop_lock_;
-  base::MessageLoop* working_loop_;
+  base::Lock working_task_runner_lock_;
+  scoped_refptr<base::SingleThreadTaskRunner> working_task_runner_;
 
   // Callback passed with UnregisterForLoopDestruction. Normally this
-  // remains unset/unused and is stored only if |working_loop_| isn't
+  // remains unset/unused and is stored only if |working_task_runner_| isn't
   // initialized by the time UnregisterForLoopDestruction is called.
   // It is safe to copy and thread safe.
   // See comments in model_safe_worker.cc for more details.
diff --git a/sync/internal_api/public/http_bridge.h b/sync/internal_api/public/http_bridge.h
index 20d8bc6..cd6106c9 100644
--- a/sync/internal_api/public/http_bridge.h
+++ b/sync/internal_api/public/http_bridge.h
@@ -15,6 +15,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/lock.h"
 #include "base/synchronization/waitable_event.h"
+#include "base/threading/thread_checker.h"
 #include "base/timer/timer.h"
 #include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request_context.h"
@@ -28,10 +29,6 @@
 
 class HttpBridgeTest;
 
-namespace base {
-class MessageLoop;
-}
-
 namespace net {
 class HttpResponseHeaders;
 class HttpUserAgentSettings;
@@ -115,12 +112,12 @@
   // Helper method to abort the request if we timed out.
   void OnURLFetchTimedOut();
 
-  // The message loop of the thread we were created on. This is the thread that
-  // will block on MakeSynchronousPost while the IO thread fetches data from
-  // the network.
+  // Used to check whether a method runs on the thread that we were created on.
+  // This is the thread that will block on MakeSynchronousPost while the IO
+  // thread fetches data from the network.
   // This should be the main syncer thread (SyncerThread) which is what blocks
   // on network IO through curl_easy_perform.
-  base::MessageLoop* const created_on_loop_;
+  base::ThreadChecker thread_checker_;
 
   // The user agent for all requests.
   const std::string user_agent_;
diff --git a/testing/android/appurify_support/java/src/org/chromium/test/support/ResultsBundleGenerator.java b/testing/android/appurify_support/java/src/org/chromium/test/support/ResultsBundleGenerator.java
index c9588d90..570a09c 100644
--- a/testing/android/appurify_support/java/src/org/chromium/test/support/ResultsBundleGenerator.java
+++ b/testing/android/appurify_support/java/src/org/chromium/test/support/ResultsBundleGenerator.java
@@ -6,25 +6,84 @@
 
 import android.os.Bundle;
 
+import java.util.List;
 import java.util.Map;
 
 /**
  * Creates a results Bundle.
  */
 public interface ResultsBundleGenerator {
+    /**
+     * Holds the results of a test.
+     */
+    public interface TestResult {
+        /**
+         * Returns the test class name.
+         */
+        public String getTestClass();
+
+        /**
+         * Returns the test case name.
+         */
+        public String getTestName();
+
+        /**
+         * Retunrs the index of the test within the suite.
+         */
+        public int getTestIndex();
+
+        /**
+         * Returns a message for the test.
+         */
+        public String getMessage();
+
+        /**
+         * Returns the test case log.
+         */
+        public String getLog();
+
+        /**
+         * Returns the status of the test.
+         */
+        public TestStatus getStatus();
+    }
 
     /** Indicates the state of a test.
      */
-    static enum TestResult {
-        PASSED, FAILED, ERROR, UNKNOWN
+    public static enum TestStatus { PASSED, FAILED, ERROR, UNKNOWN }
+
+    /** Holds the processed data to be sent by the Instrumentation to report the status of a test
+        case.
+     */
+    public static class TestCaseResult {
+        public final Bundle mBundle;
+        public final int mStatusCode;
+
+        public TestCaseResult(int statusCode, Bundle bundle) {
+            mBundle = bundle;
+            mStatusCode = statusCode;
+        }
     }
 
-    /** Creates a bundle of test results from the provided raw results.
+    /** Generates intermediate results for each individual test case to be sent to the
+        instrumentation framework.
+
+        @returns a list of TestCaseResults that can be used to send status updates.
 
         Note: actual bundle content and format may vary.
 
         @param rawResults A map between test names and test results.
      */
-    Bundle generate(Map<String, TestResult> rawResults);
-}
+    List<TestCaseResult> generateIntermediateTestResults(Map<String, TestResult> rawResults);
 
+    /**
+      Creates a bundle of test results from the provided raw results.
+
+      Note: actual bundle content and format may vary.
+      @param testsPassed The number of passed test cases.
+      @param testsFailed The number of failed test cases.
+      @param testsErrored The number of errored test cases.
+      @param totalTests The number of test cases.
+     */
+    Bundle generate(int testsPassed, int testsFailed, int testsErrored, int totalTests);
+}
diff --git a/testing/android/appurify_support/java/src/org/chromium/test/support/RobotiumBundleGenerator.java b/testing/android/appurify_support/java/src/org/chromium/test/support/RobotiumBundleGenerator.java
index d102692..681e7c61 100644
--- a/testing/android/appurify_support/java/src/org/chromium/test/support/RobotiumBundleGenerator.java
+++ b/testing/android/appurify_support/java/src/org/chromium/test/support/RobotiumBundleGenerator.java
@@ -6,54 +6,88 @@
 
 import android.app.Instrumentation;
 import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 /**
  * Creates a results bundle that emulates the one created by Robotium.
  */
 public class RobotiumBundleGenerator implements ResultsBundleGenerator {
-
     private static final String TAG = "RobotiumBundleGenerator";
 
-    public Bundle generate(Map<String, ResultsBundleGenerator.TestResult> rawResults) {
-        Bundle resultsBundle = new Bundle();
+    public List<ResultsBundleGenerator.TestCaseResult> generateIntermediateTestResults(
+            Map<String, ResultsBundleGenerator.TestResult> rawResults) {
         if (rawResults.isEmpty()) {
-            return resultsBundle;
+            return new ArrayList<ResultsBundleGenerator.TestCaseResult>();
         }
 
-        int testsPassed = 0;
-        int testsFailed = 0;
-        int testsErrored = 0;
+        List<ResultsBundleGenerator.TestCaseResult> testCaseResultList =
+                new ArrayList<ResultsBundleGenerator.TestCaseResult>();
+        int totalTests = rawResults.size();
 
         for (Map.Entry<String, ResultsBundleGenerator.TestResult> entry : rawResults.entrySet()) {
-            switch (entry.getValue()) {
+            ResultsBundleGenerator.TestResult result = entry.getValue();
+            Bundle startBundle = new Bundle();
+            startBundle.putString(Instrumentation.REPORT_KEY_IDENTIFIER,
+                    InstrumentationTestRunner.REPORT_VALUE_ID);
+            startBundle.putString(
+                    InstrumentationTestRunner.REPORT_KEY_NAME_CLASS, result.getTestClass());
+            startBundle.putString(
+                    InstrumentationTestRunner.REPORT_KEY_NAME_TEST, result.getTestName());
+            startBundle.putInt(
+                    InstrumentationTestRunner.REPORT_KEY_NUM_CURRENT, result.getTestIndex());
+            startBundle.putInt(InstrumentationTestRunner.REPORT_KEY_NUM_TOTAL, totalTests);
+            startBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                    String.format("%n%s.%s", result.getTestClass(), result.getTestName()));
+            testCaseResultList.add(new ResultsBundleGenerator.TestCaseResult(
+                    InstrumentationTestRunner.REPORT_VALUE_RESULT_START, startBundle));
+
+            Bundle resultBundle = new Bundle(startBundle);
+            resultBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, result.getMessage());
+            switch (result.getStatus()) {
                 case PASSED:
-                    ++testsPassed;
+                    testCaseResultList.add(new ResultsBundleGenerator.TestCaseResult(
+                            InstrumentationTestRunner.REPORT_VALUE_RESULT_OK, resultBundle));
                     break;
                 case FAILED:
                     // TODO(jbudorick): Remove this log message once AMP execution and
                     // results handling has been stabilized.
                     Log.d(TAG, "FAILED: " + entry.getKey());
-                    ++testsFailed;
+                    resultBundle.putString(
+                            InstrumentationTestRunner.REPORT_KEY_STACK, result.getLog());
+                    testCaseResultList.add(new ResultsBundleGenerator.TestCaseResult(
+                            InstrumentationTestRunner.REPORT_VALUE_RESULT_FAILURE, resultBundle));
                     break;
                 case UNKNOWN:
-                    ++testsErrored;
+                    testCaseResultList.add(new ResultsBundleGenerator.TestCaseResult(
+                            InstrumentationTestRunner.REPORT_VALUE_RESULT_ERROR, resultBundle));
                     break;
                 default:
                     Log.w(TAG, "Unhandled: " + entry.getKey() + ", "
                             + entry.getValue().toString());
+                    testCaseResultList.add(new ResultsBundleGenerator.TestCaseResult(
+                            InstrumentationTestRunner.REPORT_VALUE_RESULT_ERROR, resultBundle));
                     break;
             }
         }
+        return testCaseResultList;
+    }
 
+    public Bundle generate(int testsPassed, int testsFailed, int testsErrored, int totalTests) {
+        Bundle resultsBundle = new Bundle();
         StringBuilder resultBuilder = new StringBuilder();
         if (testsFailed > 0 || testsErrored > 0) {
             resultBuilder.append("\nFAILURES!!! ")
-                    .append("Tests run: ").append(Integer.toString(rawResults.size()))
-                    .append(", Failures: ").append(Integer.toString(testsFailed))
-                    .append(", Errors: ").append(Integer.toString(testsErrored));
+                    .append("Tests run: ")
+                    .append(Integer.toString(totalTests))
+                    .append(", Failures: ")
+                    .append(Integer.toString(testsFailed))
+                    .append(", Errors: ")
+                    .append(Integer.toString(testsErrored));
         } else {
             resultBuilder.append("\nOK (" + Integer.toString(testsPassed) + " tests)");
         }
diff --git a/testing/android/driver/java/src/org/chromium/test/driver/OnDeviceInstrumentationDriver.java b/testing/android/driver/java/src/org/chromium/test/driver/OnDeviceInstrumentationDriver.java
index 1003e6a..1cfd557cb 100644
--- a/testing/android/driver/java/src/org/chromium/test/driver/OnDeviceInstrumentationDriver.java
+++ b/testing/android/driver/java/src/org/chromium/test/driver/OnDeviceInstrumentationDriver.java
@@ -189,12 +189,23 @@
             sendTestStatus(status, testClass, testMethod, null);
         }
 
+        /** Holds a summary of all test results. */
+        private class TestResultSummary {
+            public int totalTests;
+            public int testsPassed;
+            public int testsFailed;
+
+            public int testsErrored() {
+                return totalTests - testsPassed - testsFailed;
+            }
+        }
+
         /** Run the tests. */
         @Override
         public void run() {
-            final HashMap<String, ResultsBundleGenerator.TestResult> finished =
-                    new HashMap<String, ResultsBundleGenerator.TestResult>();
-            final Object statusLock = new Object();
+            final HashMap<String, ResultsBundleGenerator.TestStatus> finished =
+                    new HashMap<String, ResultsBundleGenerator.TestStatus>();
+            final TestResultSummary testResults = new TestResultSummary();
 
             try {
                 TestStatusReceiver r = new TestStatusReceiver();
@@ -203,8 +214,9 @@
                     public void testStarted(String testClass, String testMethod) {
                         sendTestStatus(InstrumentationTestRunner.REPORT_VALUE_RESULT_START,
                                 testClass, testMethod);
-                        synchronized (statusLock) {
-                            statusLock.notify();
+                        synchronized (testResults) {
+                            testResults.totalTests++;
+                            testResults.notify();
                         }
                     }
                 });
@@ -213,10 +225,11 @@
                     public void testPassed(String testClass, String testMethod) {
                         sendTestStatus(InstrumentationTestRunner.REPORT_VALUE_RESULT_OK, testClass,
                                 testMethod);
-                        synchronized (statusLock) {
+                        synchronized (testResults) {
                             finished.put(testClass + "#" + testMethod,
-                                    ResultsBundleGenerator.TestResult.PASSED);
-                            statusLock.notify();
+                                    ResultsBundleGenerator.TestStatus.PASSED);
+                            testResults.testsPassed++;
+                            testResults.notify();
                         }
                     }
                 });
@@ -225,10 +238,11 @@
                     public void testFailed(String testClass, String testMethod, String stackTrace) {
                         sendTestStatus(InstrumentationTestRunner.REPORT_VALUE_RESULT_ERROR,
                                 testClass, testMethod, stackTrace);
-                        synchronized (statusLock) {
+                        synchronized (testResults) {
                             finished.put(testClass + "#" + testMethod,
-                                    ResultsBundleGenerator.TestResult.FAILED);
-                            statusLock.notify();
+                                    ResultsBundleGenerator.TestStatus.FAILED);
+                            testResults.testsFailed++;
+                            testResults.notify();
                         }
                     }
                 });
@@ -236,8 +250,8 @@
                     @Override
                     public void heartbeat() {
                         Log.i(TAG, "Heartbeat received.");
-                        synchronized (statusLock) {
-                            statusLock.notify();
+                        synchronized (testResults) {
+                            testResults.notify();
                         }
                     }
                 });
@@ -260,13 +274,13 @@
 
                     getContext().startActivity(slaveIntent);
 
-                    synchronized (statusLock) {
+                    synchronized (testResults) {
                         while (!finished.containsKey(t)) {
                             long waitStart = System.currentTimeMillis();
-                            statusLock.wait(TEST_WAIT_TIMEOUT);
+                            testResults.wait(TEST_WAIT_TIMEOUT);
                             if (System.currentTimeMillis() - waitStart > TEST_WAIT_TIMEOUT) {
                                 Log.e(TAG, t + " has gone missing and is assumed to be dead.");
-                                finished.put(t, ResultsBundleGenerator.TestResult.FAILED);
+                                finished.put(t, ResultsBundleGenerator.TestStatus.FAILED);
                                 break;
                             }
                         }
@@ -278,7 +292,8 @@
                 fail("Interrupted while running tests.", e);
                 return;
             }
-            pass(new RobotiumBundleGenerator().generate(finished));
+            pass(new RobotiumBundleGenerator().generate(testResults.testsPassed,
+                    testResults.testsFailed, testResults.testsErrored(), testResults.totalTests));
         }
 
     }
diff --git a/testing/android/native_test/java/AndroidManifest.xml.jinja2 b/testing/android/native_test/java/AndroidManifest.xml.jinja2
index 9f46ae52..cdd7b544 100644
--- a/testing/android/native_test/java/AndroidManifest.xml.jinja2
+++ b/testing/android/native_test/java/AndroidManifest.xml.jinja2
@@ -23,6 +23,7 @@
 
     <application android:label="NativeTests"
             android:name="org.chromium.base.BaseChromiumApplication">
+        <uses-library android:name="android.test.runner"/>
         {% if use_native_activity == 'true' %}
         <activity android:name=".NativeUnitTestNativeActivity"
                 android:label="NativeTest"
diff --git a/testing/android/native_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.java b/testing/android/native_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.java
index 80c7680..d0a2922 100644
--- a/testing/android/native_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.java
+++ b/testing/android/native_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.java
@@ -62,7 +62,7 @@
     private static final String DEFAULT_NATIVE_TEST_ACTIVITY =
             "org.chromium.native_test.NativeUnitTestActivity";
     private static final Pattern RE_TEST_OUTPUT =
-            Pattern.compile("\\[ *([^ ]*) *\\] ?([^ ]+)( .*)?$");
+            Pattern.compile("\\[ *([^ ]*) *\\] ?([^ \\.]+)\\.([^ \\.]+)( .*)?$");
 
     private ResultsBundleGenerator mBundleGenerator = new RobotiumBundleGenerator();
     private Handler mHandler = new Handler();
@@ -70,8 +70,7 @@
     private SparseArray<ShardMonitor> mMonitors = new SparseArray<ShardMonitor>();
     private String mNativeTestActivity;
     private TestStatusReceiver mReceiver;
-    private Map<String, ResultsBundleGenerator.TestResult> mResults =
-            new HashMap<String, ResultsBundleGenerator.TestResult>();
+    private TestResults mResults = new TestResults();
     private Queue<ArrayList<String>> mShards = new ArrayDeque<ArrayList<String>>();
     private long mShardNanoTimeout = DEFAULT_SHARD_NANO_TIMEOUT;
     private int mShardSizeLimit = DEFAULT_SHARD_SIZE_LIMIT;
@@ -181,6 +180,26 @@
         mHandler.post(new ShardStarter());
     }
 
+    /** Holds the results of a test run. */
+    private static class TestResults {
+        Map<String, ResultsBundleGenerator.TestResult> mResults =
+                new HashMap<String, ResultsBundleGenerator.TestResult>();
+        int mTestsPassed = 0;
+        int mTestsFailed = 0;
+        int mTestsErrored = 0;
+
+        public void merge(TestResults other) {
+            mResults.putAll(other.mResults);
+            mTestsPassed += other.mTestsPassed;
+            mTestsFailed += other.mTestsFailed;
+            mTestsErrored += other.mTestsErrored;
+        }
+
+        public int total() {
+            return mTestsPassed + mTestsFailed + mTestsErrored;
+        }
+    }
+
     /** Monitors a test shard's execution. */
     private class ShardMonitor implements Runnable {
         private static final int MONITOR_FREQUENCY_MS = 1000;
@@ -271,23 +290,86 @@
                     Log.e(TAG, "%d may still be alive.", mPid, e);
                 }
             }
-            mResults.putAll(parseResults());
+            mResults.merge(parseResults());
 
             if (mShards != null && !mShards.isEmpty()) {
                 mHandler.post(new ShardStarter());
             } else {
-                finish(Activity.RESULT_OK, mBundleGenerator.generate(mResults));
+                sendResultsAndFinish(mResults);
             }
         }
     }
 
+    private void sendResultsAndFinish(TestResults results) {
+        for (ResultsBundleGenerator.TestCaseResult result :
+                mBundleGenerator.generateIntermediateTestResults(results.mResults)) {
+            sendStatus(result.mStatusCode, result.mBundle);
+        }
+        Bundle bundle = mBundleGenerator.generate(
+                results.mTestsPassed, results.mTestsFailed, results.mTestsErrored, results.total());
+        finish(Activity.RESULT_OK, bundle);
+    }
+
+    private static class NativeTestResult implements ResultsBundleGenerator.TestResult {
+        private String mTestClass;
+        private String mTestName;
+        private int mTestIndex;
+        private StringBuilder mLogBuilder = new StringBuilder();
+        private ResultsBundleGenerator.TestStatus mStatus =
+                ResultsBundleGenerator.TestStatus.UNKNOWN;
+
+        private NativeTestResult(String testClass, String testName, int index) {
+            mTestClass = testClass;
+            mTestName = testName;
+            mTestIndex = index;
+        }
+
+        @Override
+        public String getTestClass() {
+            return mTestClass;
+        }
+
+        @Override
+        public String getTestName() {
+            return mTestName;
+        }
+
+        @Override
+        public int getTestIndex() {
+            return mTestIndex;
+        }
+
+        @Override
+        public String getMessage() {
+            return mStatus.toString();
+        }
+
+        @Override
+        public String getLog() {
+            return mLogBuilder.toString();
+        }
+
+        public void appendToLog(String logLine) {
+            mLogBuilder.append(logLine);
+            mLogBuilder.append("\n");
+        }
+
+        @Override
+        public ResultsBundleGenerator.TestStatus getStatus() {
+            return mStatus;
+        }
+
+        public void setStatus(ResultsBundleGenerator.TestStatus status) {
+            mStatus = status;
+        }
+    }
+
     /**
      *  Generates a map between test names and test results from the instrumented Activity's
      *  output.
      */
-    private Map<String, ResultsBundleGenerator.TestResult> parseResults() {
-        Map<String, ResultsBundleGenerator.TestResult> results =
-                new HashMap<String, ResultsBundleGenerator.TestResult>();
+    private TestResults parseResults() {
+        TestResults results = new TestResults();
 
         BufferedReader r = null;
 
@@ -300,17 +382,39 @@
             r = new BufferedReader(new InputStreamReader(
                     new BufferedInputStream(new FileInputStream(mStdoutFile))));
 
+            NativeTestResult testResult = null;
+            int testNum = 0;
             for (String l = r.readLine(); l != null && !l.equals("<<ScopedMainEntryLogger");
                     l = r.readLine()) {
                 Matcher m = RE_TEST_OUTPUT.matcher(l);
                 if (m.matches()) {
+                    String testClass = m.group(2);
+                    String testName = m.group(3);
                     if (m.group(1).equals("RUN")) {
-                        results.put(m.group(2), ResultsBundleGenerator.TestResult.UNKNOWN);
+                        testResult = new NativeTestResult(testClass, testName, ++testNum);
+                        results.mResults.put(
+                                String.format("%s.%s", testClass, testName), testResult);
                     } else if (m.group(1).equals("FAILED")) {
-                        results.put(m.group(2), ResultsBundleGenerator.TestResult.FAILED);
+                        if (testResult == null) {
+                            Log.e(TAG, "Test %s.%s failed without running.", testClass, testName);
+                            continue;
+                        }
+                        results.mTestsFailed++;
+                        testResult.setStatus(ResultsBundleGenerator.TestStatus.FAILED);
+                        testResult = null;
                     } else if (m.group(1).equals("OK")) {
-                        results.put(m.group(2), ResultsBundleGenerator.TestResult.PASSED);
+                        if (testResult == null) {
+                            Log.e(TAG, "Test %s.%s succeeded without running.", testClass,
+                                    testName);
+                            continue;
+                        }
+                        results.mTestsPassed++;
+                        testResult.setStatus(ResultsBundleGenerator.TestStatus.PASSED);
+                        testResult = null;
                     }
+                } else if (testResult != null) {
+                    // We are inside a test. Let's collect log data in case there is a failure.
+                    testResult.appendToLog(l);
                 }
                 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, l + "\n");
                 sendStatus(0, mLogBundle);
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index eadceec..f754fb2 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -125,6 +125,9 @@
 crbug.com/339597 http/tests/navigation/back-to-redirect-with-frame.php [ Pass Timeout ]
 crbug.com/473718 http/tests/navigation/beacon-cross-origin-redirect.html [ Failure Pass ]
 
+# TODO(fs): Update after baselines for crbug.com/617799 and crbug.com/619630.
+# crbug.com/603956 svg/text/text-viewbox-rescale.html [ NeedsManualRebaseline ]
+
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-basic.html [ Pass Failure ]
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-consume-deltas.html [ Pass Failure ]
 crbug.com/410974 fast/scroll-behavior/scroll-customization/scrollstate-consume-deltas-throw.html [ Pass Failure ]
@@ -929,8 +932,8 @@
 crbug.com/472330 fast/writing-mode/box-shadow-vertical-lr.html [ Failure ]
 crbug.com/472330 fast/writing-mode/box-shadow-vertical-rl.html [ Failure ]
 
-# Flaky on Win10
-crbug.com/619539 [ Win10 ] http/tests/workers/terminate-during-sync-operation-file.html [ Pass Timeout ]
+# Flaky on Win10 and Win7
+crbug.com/619539 [ Win ] http/tests/workers/terminate-during-sync-operation-file.html [ Pass Timeout ]
 
 crbug.com/466200 svg/custom/repaint-on-constant-size-change.svg [ Failure ]
 
@@ -1221,6 +1224,7 @@
 # crbug.com/619103 paint/invalidation/animated-gif.html [ Pass Failure ]
 # crbug.com/619103 paint/invalidation/animated-gif-background.html [ Pass Failure ]
 # crbug.com/619103 paint/invalidation/animated-gif-background-offscreen.html [ Pass Failure ]
+# TODO(fs): Recheck after landing the baselines for crbug.com/603956.
 # crbug.com/619103 [ Win ] svg/text/text-viewbox-rescale.html [ Pass Failure ]
 
 crbug.com/443596 media/sources-fallback-codecs.html [ Pass Failure ]
@@ -1329,6 +1333,9 @@
 
 crbug.com/399951 http/tests/mime/javascript-mimetype-usecounters.html [ Pass Failure ]
 
+crbug.com/621915 [ Mac10.9 ] svg/custom/createImageElement2.xhtml [ Pass Failure ]
+crbug.com/621915 [ Mac10.9 ] svg/custom/pointer-events-image.svg [ Pass Failure ]
+
 crbug.com/602193 inspector/extensions/extensions-resources.html [ Pass Failure ]
 
 crbug.com/579493 http/tests/security/xss-DENIED-xsl-document-securityOrigin.xml [ Timeout ]
@@ -1387,9 +1394,6 @@
 
 crbug.com/599975 [ Android ] media/video-autoplay.html [ Crash Timeout ]
 
-crbug.com/617443 [ Linux Mac Win7 ] printing/thead-repeats-at-top-of-each-page.html [ NeedsRebaseline ]
-crbug.com/617443 [ Linux Mac Win7 ] virtual/threaded/printing/thead-repeats-at-top-of-each-page.html [ NeedsRebaseline ]
-
 # DocumentWriteEvaluator is still experimental
 crbug.com/599115 http/tests/preload/document-write [ Failure ]
 crbug.com/599115 http/tests/preload/document-write/document_write_no_preload.html [ Pass ]
@@ -1507,12 +1511,10 @@
 
 crbug.com/614509 [ Win ] inspector/elements/styles-2/pseudo-elements.html [ Pass Timeout ]
 
-crbug.com/618399 fast/js/regress/to-int32-boolean.html [ Pass Timeout ]
-
-
 crbug.com/484632 css3/flexbox/stretch-input-in-column.html [ Failure ]
 
 # Note: this test was previously marked as slow on Debug builds. Skipping until crash is fixed
 crbug.com/619978 fast/css/giant-stylesheet-crash.html [ Skip ]
 
 crbug.com/621840 [ Win7 ] svg/hixie/perf/005.xml [ Pass Timeout ]
+crbug.com/621892 [ Win7 Linux ] css3/filters/effect-hue-rotate-hw.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/fragmentation/single-line-cells-in-multiple-table-sections-expected.txt b/third_party/WebKit/LayoutTests/fragmentation/single-line-cells-in-multiple-table-sections-expected.txt
new file mode 100644
index 0000000..e4384d2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fragmentation/single-line-cells-in-multiple-table-sections-expected.txt
@@ -0,0 +1,27 @@
+crbug.com/99124: Table rows shouldn't straddle page boundaries.
+
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+Te	xt
+PASS
+PASS
diff --git a/third_party/WebKit/LayoutTests/fragmentation/single-line-cells-in-multiple-table-sections.html b/third_party/WebKit/LayoutTests/fragmentation/single-line-cells-in-multiple-table-sections.html
new file mode 100644
index 0000000..b45b3532e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fragmentation/single-line-cells-in-multiple-table-sections.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<style>
+table {
+    border-collapse: collapse;
+}
+td {
+    background-color: #ddd;
+    border: 1px solid black;
+}
+tr {
+    break-inside: avoid;
+}
+</style>
+<p>crbug.com/99124: Table rows shouldn't straddle page boundaries.</p>
+<div style="-webkit-columns:6; line-height: 20px; column-fill: auto; height:190px; background-color: yellow;">
+    <table>
+        <tbody>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        </tbody>
+        <tbody>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td class="td" data-total-y=191>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        </tbody>
+        <tbody>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td class="td" data-total-y=381>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        <tr><td>Te</td><td>xt</td></tr>
+        </tbody>
+    </table>
+</div>
+<div id="console"></div>
+<script src="../resources/check-layout.js"></script>
+<script>
+    checkLayout(".td", document.getElementById("console"));
+</script>
+
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-dom-test.js b/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-dom-test.js
index c5b82638..df41f061 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-dom-test.js
+++ b/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-dom-test.js
@@ -11,7 +11,7 @@
     function testBody(node, done)
     {
         var editorElement = InspectorTest.editNodePart(node, "webkit-html-attribute");
-        editorElement.dispatchEvent(InspectorTest.createKeyEvent("Tab"));
+        eventSender.keyDown("Tab");
 
         InspectorTest.deprecatedRunAfterPendingDispatches(testContinuation);
 
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-trimmed-attribute-value.html b/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-trimmed-attribute-value.html
index 2daff35..3a5bfd1 100644
--- a/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-trimmed-attribute-value.html
+++ b/third_party/WebKit/LayoutTests/inspector/elements/edit/edit-trimmed-attribute-value.html
@@ -19,7 +19,7 @@
         InspectorTest.addResult("textContent when editing 'href'");
         InspectorTest.addResult(treeElement.title.textContent);
 
-        textElement.dispatchEvent(InspectorTest.createKeyEvent("Tab"));
+        eventSender.keyDown("Tab");
         InspectorTest.addResult("textContent after moving to 'id'");
         InspectorTest.addResult(treeElement.title.textContent);
 
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping-expected.txt
index 340bd8b..ef358fb 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping-expected.txt
@@ -119,3 +119,12 @@
 (suspend state changed: true)
 (suspend state changed: false)
 
+Running: testNodeJSWrapper
+Adding file system.
+Workspace event: UISourceCodeAdded: file:///var/www/html/foo.js.
+Workspace event: UISourceCodeAdded: file:///var/www/html/bar.js.
+Workspace event: UISourceCodeAdded: debugger:///VM5 foo.js.
+Is diverged: false
+Workspace event: UISourceCodeAdded: debugger:///VM6 bar.js.
+Is diverged: false
+
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping.html
index 29e47e34..c3bc705 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping.html
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/file-system-project-mapping.html
@@ -378,6 +378,40 @@
                 fs.reportRemoved();
                 next();
             }
+        },
+
+        function testNodeJSWrapper(next)
+        {
+            createWorkspaceWithTarget();
+            InspectorTest.addResult("Adding file system.");
+            var fs = new InspectorTest.TestFileSystem("file:///var/www");
+            var content = "var a = 1;"
+            var folder = fs.root.mkdir("html");
+            folder.addFile("foo.js", "#!/usr/bin/env node;\n" + content);
+            folder.addFile("bar.js", content);
+            fs.root.addFile(".devtools", JSON.stringify({ mappings: [ { folder: "/html/", url: "http://localhost/h1/" } ]}));
+            fs.reportCreated(fileSystemCreated);
+
+            function fileSystemCreated()
+            {
+                debugger;
+                var uiSourceCodeFoo = InspectorTest.testWorkspace.uiSourceCode(fileSystemProjectId, "file:///var/www/html/foo.js");
+                var uiSourceCodeBar = InspectorTest.testWorkspace.uiSourceCode(fileSystemProjectId, "file:///var/www/html/bar.js");
+
+                var nodePrefix = "(function (exports, require, module, __filename, __dirname) { \n";
+                var nodeSuffix = "\n});";
+
+                var scriptFoo = InspectorTest.createScriptMock("http://localhost/h1/foo.js", 0, 0, false, nodePrefix + content + nodeSuffix, InspectorTest.testTargetManager.targets()[0]);
+                defaultScriptMapping.addScript(scriptFoo);
+                resourceScriptMapping.addScript(scriptFoo);
+                InspectorTest.addResult("Is diverged: " + resourceScriptMapping.scriptFile(uiSourceCodeFoo)._isDiverged());
+
+                var scriptBar = InspectorTest.createScriptMock("http://localhost/h1/bar.js", 0, 0, false, nodePrefix + content + nodeSuffix, InspectorTest.testTargetManager.targets()[0]);
+                defaultScriptMapping.addScript(scriptBar);
+                resourceScriptMapping.addScript(scriptBar);
+                InspectorTest.addResult("Is diverged: " + resourceScriptMapping.scriptFile(uiSourceCodeBar)._isDiverged());
+                next();
+            }
         }
     ]);
 };
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt
new file mode 100644
index 0000000..670b52e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt
@@ -0,0 +1,42 @@
+layer at (0,0) size 480x360
+  LayoutView at (0,0) size 480x360
+layer at (0,0) size 480x360
+  LayoutSVGRoot {svg} at (0,0) size 480x360
+    LayoutSVGContainer {g} at (0,20) size 399x256
+      LayoutSVGText {text} at (60,20) size 316x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 316x19
+          chunk 1 text run 1 at (60.00,35.00) startOffset 0 endOffset 45 width 316.00: "CSS pixel coordinate to user space conversion"
+      LayoutSVGContainer {g} at (25,20) size 20x20 [transform={m=((4.00,0.00)(0.00,4.00)) t=(5.00,0.00)}]
+        LayoutSVGEllipse {circle} at (25,20) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=7.50] [cy=7.50] [r=2.50]
+        LayoutSVGEllipse {circle} at (29,24) size 12x12 [fill={[type=SOLID] [color=#FF0000]}] [cx=7.50] [cy=7.50] [r=1.50]
+      LayoutSVGText {text} at (60,70) size 332x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 332x19
+          chunk 1 text run 1 at (60.00,85.00) startOffset 0 endOffset 47 width 332.00: "Percentage coordinates to user space conversion"
+      LayoutSVGContainer {g} at (25,70) size 20x20 [transform={m=((4.00,0.00)(0.00,4.00)) t=(5.00,50.00)}]
+        LayoutSVGEllipse {circle} at (25,70) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=7.50] [cy=7.50] [r=2.50]
+        LayoutSVGEllipse {circle} at (29,73) size 13x13 [fill={[type=SOLID] [color=#FF0000]}] [cx=7.50] [cy=7.50] [r=1.50]
+      LayoutSVGText {text} at (60,125) size 289x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 289x19
+          chunk 1 text run 1 at (60.00,140.00) startOffset 0 endOffset 41 width 289.00: "CSS width/height to user space conversion"
+      LayoutSVGContainer {g} at (10,115) size 40x40 [transform={m=((4.00,0.00)(0.00,4.00)) t=(30.00,115.00)}]
+        LayoutSVGRect {rect} at (10,115) size 40x20 [fill={[type=SOLID] [color=#000000]}] [x=-5.00] [y=0.00] [width=10.00] [height=5.00]
+        LayoutSVGRect {rect} at (10,135) size 40x20 [fill={[type=SOLID] [color=#FF0000]}] [x=-5.00] [y=5.00] [width=10.00] [height=5.00]
+      LayoutSVGText {text} at (60,185) size 336x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 336x19
+          chunk 1 text run 1 at (60.00,200.00) startOffset 0 endOffset 48 width 336.00: "Percentage width/height to user space conversion"
+      LayoutSVGContainer {g} at (10,175) size 40x41 [transform={m=((4.00,0.00)(0.00,4.00)) t=(30.00,175.00)}]
+        LayoutSVGRect {rect} at (10,175) size 40x20 [fill={[type=SOLID] [color=#000000]}] [x=-5.00] [y=0.00] [width=10.00] [height=5.00]
+        LayoutSVGRect {rect} at (10,195) size 40x21 [fill={[type=SOLID] [color=#FF0000]}] [x=-5.00] [y=5.00] [width=10.00] [height=5.00]
+      LayoutSVGText {text} at (140,250) size 259x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 259x19
+          chunk 1 text run 1 at (140.00,265.00) startOffset 0 endOffset 36 width 259.00: "CSS and percentage length conversion"
+      LayoutSVGContainer {g} at (0,244) size 146x32 [transform={m=((4.00,0.00)(4.00,4.00)) t=(30.00,260.00)}]
+        LayoutSVGEllipse {circle} at (1,245) size 58x30 [fill={[type=SOLID] [color=#000000]}] [cx=0.00] [cy=0.00] [r=3.54]
+        LayoutSVGEllipse {circle} at (41,245) size 58x30 [fill={[type=SOLID] [color=#FF0000]}] [cx=10.00] [cy=0.00] [r=3.54]
+        LayoutSVGEllipse {circle} at (81,245) size 58x30 [fill={[type=SOLID] [color=#008000]}] [cx=20.00] [cy=0.00] [r=3.54]
+        LayoutSVGPath {line} at (0,244) size 117x3 [stroke={[type=SOLID] [color=#CCCCCC] [stroke width=0.50]}] [x1=-3.54] [y1=-3.54] [x2=25.00] [y2=-3.54]
+        LayoutSVGPath {line} at (29,273) size 117x3 [stroke={[type=SOLID] [color=#CCCCCC] [stroke width=0.50]}] [x1=-3.54] [y1=3.54] [x2=25.00] [y2=3.54]
+    LayoutSVGText {text} at (10,304) size 261x46 contains 1 chunk(s)
+      LayoutSVGInlineText {#text} at (0,0) size 261x46
+        chunk 1 text run 1 at (10.00,340.00) startOffset 0 endOffset 16 width 261.00: "$Revision: 1.4 $"
+    LayoutSVGRect {rect} at (0,0) size 480x360 [stroke={[type=SOLID] [color=#000000]}] [x=1.00] [y=1.00] [width=478.00] [height=358.00]
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/transforms/text-with-pattern-with-svg-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
new file mode 100644
index 0000000..e097055
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
@@ -0,0 +1,43 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  LayoutSVGRoot {svg} at (0,0) size 346x460
+    LayoutSVGContainer {g} at (0,0) size 346x460 [transform={m=((0.43,0.25)(-0.25,0.43)) t=(0.00,0.00)}]
+      LayoutSVGResourcePattern {pattern} [id="pat1"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
+        LayoutSVGRect {rect} at (0,5) size 9x13 [fill={[type=SOLID] [color=#FF0000]}] [x=5.00] [y=5.00] [width=10.00] [height=10.00]
+        LayoutSVGRect {rect} at (0,11) size 11x12 [fill={[type=SOLID] [color=#008000]}] [x=10.00] [y=10.00] [width=10.00] [height=10.00]
+      LayoutSVGRect {rect} at (0,16) size 325x225 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=PATTERN] [id="pat1"]}] [x=25.00] [y=10.00] [width=430.00] [height=60.00]
+      LayoutSVGText {text} at (25,73) size 418x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 418x16
+          chunk 1 text run 1 at (25.00,85.00) startOffset 0 endOffset 75 width 417.60: "Pattern created using red and green rectangles applied to fill of rectangle"
+      LayoutSVGResourcePattern {pattern} [id="pat2"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
+        LayoutSVGRect {rect} at (0,0) size 8x12 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=10.00] [height=10.00]
+        LayoutSVGRect {rect} at (3,4) size 12x12 [fill={[type=SOLID] [color=#008000]}] [x=10.00] [y=0.00] [width=10.00] [height=10.00]
+        LayoutSVGRect {rect} at (0,7) size 4x12 [fill={[type=SOLID] [color=#0000FF]}] [x=0.00] [y=10.00] [width=10.00] [height=10.00]
+        LayoutSVGRect {rect} at (0,11) size 11x12 [fill={[type=SOLID] [color=#FFFF00]}] [x=10.00] [y=10.00] [width=10.00] [height=10.00]
+      LayoutSVGRect {rect} at (0,82) size 287x224 [stroke={[type=PATTERN] [id="pat2"] [stroke width=20.00]}] [x=35.00] [y=110.00] [width=410.00] [height=40.00]
+      LayoutSVGText {text} at (25,163) size 322x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 322x16
+          chunk 1 text run 1 at (25.00,175.00) startOffset 0 endOffset 59 width 321.60: "Pattern of 4 rectangles applied to a stroke of a rectangle."
+      LayoutSVGResourcePattern {pattern} [id="pat3"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
+        LayoutSVGRect {rect} at (0,0) size 8x12 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=10.00] [height=10.00]
+        LayoutSVGRect {rect} at (0,7) size 4x12 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=10.00] [width=10.00] [height=10.00]
+      LayoutSVGText {text} at (25,174) size 298x57 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 298x57
+          chunk 1 text run 1 at (25.00,220.00) startOffset 0 endOffset 15 width 297.60: "Pattern on fill"
+      LayoutSVGText {text} at (25,223) size 213x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 213x16
+          chunk 1 text run 1 at (25.00,235.00) startOffset 0 endOffset 38 width 212.40: "Pattern consists of red and green rows"
+      LayoutSVGResourcePattern {pattern} [id="pat4"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
+        LayoutSVGRect {rect} at (0,0) size 8x12 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=10.00] [height=10.00]
+        LayoutSVGRect {rect} at (3,4) size 12x12 [fill={[type=SOLID] [color=#0000FF]}] [x=10.00] [y=0.00] [width=10.00] [height=10.00]
+      LayoutSVGText {text} at (25,237) size 292x47 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 292x46
+          chunk 1 text run 1 at (25.00,275.00) startOffset 0 endOffset 17 width 291.60: "Pattern on stroke"
+      LayoutSVGText {text} at (25,278) size 230x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 230x16
+          chunk 1 text run 1 at (25.00,290.00) startOffset 0 endOffset 40 width 229.20: "Pattern consists of red and blue columns"
+      LayoutSVGText {text} at (10,305) size 258x45 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 258x45
+          chunk 1 text run 1 at (10.00,340.00) startOffset 0 endOffset 16 width 258.00: "$Revision: 1.6 $"
+      LayoutSVGRect {rect} at (0,0) size 346x460 [stroke={[type=SOLID] [color=#000000]}] [x=1.00] [y=1.00] [width=478.00] [height=358.00]
diff --git a/third_party/WebKit/LayoutTests/platform/android/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt b/third_party/WebKit/LayoutTests/platform/android/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
new file mode 100644
index 0000000..d6de75899
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/android/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
@@ -0,0 +1,368 @@
+layer at (0,0) size 1046x799 scrollHeight 1548
+  LayoutView at (0,0) size 1046x799
+layer at (0,0) size 1046x1548 backgroundClip at (0,0) size 1046x799 clip at (0,0) size 1046x799
+  LayoutBlockFlow {HTML} at (0,0) size 1046x1548
+    LayoutBlockFlow {BODY} at (8,8) size 1030x1532
+      LayoutTable {TABLE} at (0,0) size 449x1532
+        LayoutTableSection {THEAD} at (0,0) size 449x44
+          LayoutTableRow {TR} at (0,2) size 449x40
+            LayoutTableCell {TH} at (2,2) size 147x40 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 145x37
+                text run at (1,1) width 145: "Column 1"
+            LayoutTableCell {TH} at (151,2) size 147x40 [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 145x37
+                text run at (1,1) width 145: "Column 2"
+            LayoutTableCell {TH} at (300,2) size 147x40 [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 145x37
+                text run at (1,1) width 145: "Column 3"
+        LayoutTableSection {TBODY} at (0,44) size 449x1488
+          LayoutTableRow {TR} at (0,0) size 449x39
+            LayoutTableCell {TD} at (2,0) size 147x39 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-1"
+            LayoutTableCell {TD} at (151,0) size 147x39 [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-1"
+            LayoutTableCell {TD} at (300,0) size 147x39 [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-1"
+          LayoutTableRow {TR} at (0,41) size 449x39
+            LayoutTableCell {TD} at (2,41) size 147x39 [r=1 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-2"
+            LayoutTableCell {TD} at (151,41) size 147x39 [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-2"
+            LayoutTableCell {TD} at (300,41) size 147x39 [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-2"
+          LayoutTableRow {TR} at (0,82) size 449x39
+            LayoutTableCell {TD} at (2,82) size 147x39 [r=2 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-3"
+            LayoutTableCell {TD} at (151,82) size 147x39 [r=2 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-3"
+            LayoutTableCell {TD} at (300,82) size 147x39 [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-3"
+          LayoutTableRow {TR} at (0,123) size 449x39
+            LayoutTableCell {TD} at (2,123) size 147x39 [r=3 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-4"
+            LayoutTableCell {TD} at (151,123) size 147x39 [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-4"
+            LayoutTableCell {TD} at (300,123) size 147x39 [r=3 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-4"
+          LayoutTableRow {TR} at (0,164) size 449x39
+            LayoutTableCell {TD} at (2,164) size 147x39 [r=4 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-5"
+            LayoutTableCell {TD} at (151,164) size 147x39 [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-5"
+            LayoutTableCell {TD} at (300,164) size 147x39 [r=4 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-5"
+          LayoutTableRow {TR} at (0,205) size 449x39
+            LayoutTableCell {TD} at (2,205) size 147x39 [r=5 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-6"
+            LayoutTableCell {TD} at (151,205) size 147x39 [r=5 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-6"
+            LayoutTableCell {TD} at (300,205) size 147x39 [r=5 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-6"
+          LayoutTableRow {TR} at (0,246) size 449x39
+            LayoutTableCell {TD} at (2,246) size 147x39 [r=6 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-7"
+            LayoutTableCell {TD} at (151,246) size 147x39 [r=6 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-7"
+            LayoutTableCell {TD} at (300,246) size 147x39 [r=6 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-7"
+          LayoutTableRow {TR} at (0,287) size 449x39
+            LayoutTableCell {TD} at (2,287) size 147x39 [r=7 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-8"
+            LayoutTableCell {TD} at (151,287) size 147x39 [r=7 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-8"
+            LayoutTableCell {TD} at (300,287) size 147x39 [r=7 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-8"
+          LayoutTableRow {TR} at (0,328) size 449x39
+            LayoutTableCell {TD} at (2,328) size 147x39 [r=8 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-9"
+            LayoutTableCell {TD} at (151,328) size 147x39 [r=8 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-9"
+            LayoutTableCell {TD} at (300,328) size 147x39 [r=8 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-9"
+          LayoutTableRow {TR} at (0,369) size 449x39
+            LayoutTableCell {TD} at (2,369) size 147x39 [r=9 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-10"
+            LayoutTableCell {TD} at (151,369) size 147x39 [r=9 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-10"
+            LayoutTableCell {TD} at (300,369) size 147x39 [r=9 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-10"
+          LayoutTableRow {TR} at (0,410) size 449x39
+            LayoutTableCell {TD} at (2,410) size 147x39 [r=10 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 63x36
+                text run at (1,1) width 63: "1-11"
+            LayoutTableCell {TD} at (151,410) size 147x39 [r=10 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 63x36
+                text run at (1,1) width 63: "2-11"
+            LayoutTableCell {TD} at (300,410) size 147x39 [r=10 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 63x36
+                text run at (1,1) width 63: "3-11"
+          LayoutTableRow {TR} at (0,451) size 449x39
+            LayoutTableCell {TD} at (2,451) size 147x39 [r=11 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-12"
+            LayoutTableCell {TD} at (151,451) size 147x39 [r=11 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-12"
+            LayoutTableCell {TD} at (300,451) size 147x39 [r=11 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-12"
+          LayoutTableRow {TR} at (0,492) size 449x39
+            LayoutTableCell {TD} at (2,492) size 147x39 [r=12 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-13"
+            LayoutTableCell {TD} at (151,492) size 147x39 [r=12 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-13"
+            LayoutTableCell {TD} at (300,492) size 147x39 [r=12 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-13"
+          LayoutTableRow {TR} at (0,533) size 449x39
+            LayoutTableCell {TD} at (2,533) size 147x39 [r=13 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-14"
+            LayoutTableCell {TD} at (151,533) size 147x39 [r=13 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-14"
+            LayoutTableCell {TD} at (300,533) size 147x39 [r=13 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-14"
+          LayoutTableRow {TR} at (0,574) size 449x39
+            LayoutTableCell {TD} at (2,574) size 147x39 [r=14 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-15"
+            LayoutTableCell {TD} at (151,574) size 147x39 [r=14 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-15"
+            LayoutTableCell {TD} at (300,574) size 147x39 [r=14 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-15"
+          LayoutTableRow {TR} at (0,615) size 449x39
+            LayoutTableCell {TD} at (2,615) size 147x39 [r=15 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-16"
+            LayoutTableCell {TD} at (151,615) size 147x39 [r=15 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-16"
+            LayoutTableCell {TD} at (300,615) size 147x39 [r=15 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-16"
+          LayoutTableRow {TR} at (0,656) size 449x39
+            LayoutTableCell {TD} at (2,656) size 147x39 [r=16 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-17"
+            LayoutTableCell {TD} at (151,656) size 147x39 [r=16 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-17"
+            LayoutTableCell {TD} at (300,656) size 147x39 [r=16 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-17"
+          LayoutTableRow {TR} at (0,697) size 449x39
+            LayoutTableCell {TD} at (2,697) size 147x39 [r=17 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-18"
+            LayoutTableCell {TD} at (151,697) size 147x39 [r=17 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-18"
+            LayoutTableCell {TD} at (300,697) size 147x39 [r=17 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-18"
+          LayoutTableRow {TR} at (0,738) size 449x47
+            LayoutTableCell {TD} at (2,791) size 147x39 [r=18 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-19"
+            LayoutTableCell {TD} at (151,791) size 147x39 [r=18 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-19"
+            LayoutTableCell {TD} at (300,791) size 147x39 [r=18 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-19"
+          LayoutTableRow {TR} at (0,832) size 449x39
+            LayoutTableCell {TD} at (2,832) size 147x39 [r=19 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-20"
+            LayoutTableCell {TD} at (151,832) size 147x39 [r=19 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-20"
+            LayoutTableCell {TD} at (300,832) size 147x39 [r=19 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-20"
+          LayoutTableRow {TR} at (0,873) size 449x39
+            LayoutTableCell {TD} at (2,873) size 147x39 [r=20 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-21"
+            LayoutTableCell {TD} at (151,873) size 147x39 [r=20 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-21"
+            LayoutTableCell {TD} at (300,873) size 147x39 [r=20 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-21"
+          LayoutTableRow {TR} at (0,914) size 449x39
+            LayoutTableCell {TD} at (2,914) size 147x39 [r=21 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-22"
+            LayoutTableCell {TD} at (151,914) size 147x39 [r=21 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-22"
+            LayoutTableCell {TD} at (300,914) size 147x39 [r=21 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-22"
+          LayoutTableRow {TR} at (0,955) size 449x39
+            LayoutTableCell {TD} at (2,955) size 147x39 [r=22 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-23"
+            LayoutTableCell {TD} at (151,955) size 147x39 [r=22 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-23"
+            LayoutTableCell {TD} at (300,955) size 147x39 [r=22 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-23"
+          LayoutTableRow {TR} at (0,996) size 449x39
+            LayoutTableCell {TD} at (2,996) size 147x39 [r=23 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-24"
+            LayoutTableCell {TD} at (151,996) size 147x39 [r=23 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-24"
+            LayoutTableCell {TD} at (300,996) size 147x39 [r=23 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-24"
+          LayoutTableRow {TR} at (0,1037) size 449x39
+            LayoutTableCell {TD} at (2,1037) size 147x39 [r=24 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-25"
+            LayoutTableCell {TD} at (151,1037) size 147x39 [r=24 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-25"
+            LayoutTableCell {TD} at (300,1037) size 147x39 [r=24 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-25"
+          LayoutTableRow {TR} at (0,1078) size 449x39
+            LayoutTableCell {TD} at (2,1078) size 147x39 [r=25 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-26"
+            LayoutTableCell {TD} at (151,1078) size 147x39 [r=25 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-26"
+            LayoutTableCell {TD} at (300,1078) size 147x39 [r=25 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-26"
+          LayoutTableRow {TR} at (0,1119) size 449x39
+            LayoutTableCell {TD} at (2,1119) size 147x39 [r=26 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-27"
+            LayoutTableCell {TD} at (151,1119) size 147x39 [r=26 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-27"
+            LayoutTableCell {TD} at (300,1119) size 147x39 [r=26 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-27"
+          LayoutTableRow {TR} at (0,1160) size 449x39
+            LayoutTableCell {TD} at (2,1160) size 147x39 [r=27 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-28"
+            LayoutTableCell {TD} at (151,1160) size 147x39 [r=27 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-28"
+            LayoutTableCell {TD} at (300,1160) size 147x39 [r=27 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-28"
+          LayoutTableRow {TR} at (0,1201) size 449x39
+            LayoutTableCell {TD} at (2,1201) size 147x39 [r=28 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-29"
+            LayoutTableCell {TD} at (151,1201) size 147x39 [r=28 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-29"
+            LayoutTableCell {TD} at (300,1201) size 147x39 [r=28 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-29"
+          LayoutTableRow {TR} at (0,1242) size 449x39
+            LayoutTableCell {TD} at (2,1242) size 147x39 [r=29 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-30"
+            LayoutTableCell {TD} at (151,1242) size 147x39 [r=29 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-30"
+            LayoutTableCell {TD} at (300,1242) size 147x39 [r=29 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-30"
+          LayoutTableRow {TR} at (0,1283) size 449x39
+            LayoutTableCell {TD} at (2,1283) size 147x39 [r=30 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-31"
+            LayoutTableCell {TD} at (151,1283) size 147x39 [r=30 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-31"
+            LayoutTableCell {TD} at (300,1283) size 147x39 [r=30 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-31"
+          LayoutTableRow {TR} at (0,1324) size 449x39
+            LayoutTableCell {TD} at (2,1324) size 147x39 [r=31 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-32"
+            LayoutTableCell {TD} at (151,1324) size 147x39 [r=31 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-32"
+            LayoutTableCell {TD} at (300,1324) size 147x39 [r=31 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-32"
+          LayoutTableRow {TR} at (0,1365) size 449x39
+            LayoutTableCell {TD} at (2,1365) size 147x39 [r=32 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-33"
+            LayoutTableCell {TD} at (151,1365) size 147x39 [r=32 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-33"
+            LayoutTableCell {TD} at (300,1365) size 147x39 [r=32 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-33"
+          LayoutTableRow {TR} at (0,1406) size 449x39
+            LayoutTableCell {TD} at (2,1406) size 147x39 [r=33 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-34"
+            LayoutTableCell {TD} at (151,1406) size 147x39 [r=33 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-34"
+            LayoutTableCell {TD} at (300,1406) size 147x39 [r=33 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-34"
+          LayoutTableRow {TR} at (0,1447) size 449x39
+            LayoutTableCell {TD} at (2,1447) size 147x39 [r=34 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-35"
+            LayoutTableCell {TD} at (151,1447) size 147x39 [r=34 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-35"
+            LayoutTableCell {TD} at (300,1447) size 147x39 [r=34 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-35"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt
index 670b52e..dc42191 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-02-b-expected.txt
@@ -2,33 +2,33 @@
   LayoutView at (0,0) size 480x360
 layer at (0,0) size 480x360
   LayoutSVGRoot {svg} at (0,0) size 480x360
-    LayoutSVGContainer {g} at (0,20) size 399x256
-      LayoutSVGText {text} at (60,20) size 316x19 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 316x19
+    LayoutSVGContainer {g} at (0,20) size 400x256
+      LayoutSVGText {text} at (60,20) size 317x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 317x19
           chunk 1 text run 1 at (60.00,35.00) startOffset 0 endOffset 45 width 316.00: "CSS pixel coordinate to user space conversion"
       LayoutSVGContainer {g} at (25,20) size 20x20 [transform={m=((4.00,0.00)(0.00,4.00)) t=(5.00,0.00)}]
         LayoutSVGEllipse {circle} at (25,20) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=7.50] [cy=7.50] [r=2.50]
         LayoutSVGEllipse {circle} at (29,24) size 12x12 [fill={[type=SOLID] [color=#FF0000]}] [cx=7.50] [cy=7.50] [r=1.50]
-      LayoutSVGText {text} at (60,70) size 332x19 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 332x19
+      LayoutSVGText {text} at (60,70) size 333x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 333x19
           chunk 1 text run 1 at (60.00,85.00) startOffset 0 endOffset 47 width 332.00: "Percentage coordinates to user space conversion"
       LayoutSVGContainer {g} at (25,70) size 20x20 [transform={m=((4.00,0.00)(0.00,4.00)) t=(5.00,50.00)}]
         LayoutSVGEllipse {circle} at (25,70) size 20x20 [fill={[type=SOLID] [color=#000000]}] [cx=7.50] [cy=7.50] [r=2.50]
         LayoutSVGEllipse {circle} at (29,73) size 13x13 [fill={[type=SOLID] [color=#FF0000]}] [cx=7.50] [cy=7.50] [r=1.50]
-      LayoutSVGText {text} at (60,125) size 289x19 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 289x19
+      LayoutSVGText {text} at (60,125) size 290x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 290x19
           chunk 1 text run 1 at (60.00,140.00) startOffset 0 endOffset 41 width 289.00: "CSS width/height to user space conversion"
       LayoutSVGContainer {g} at (10,115) size 40x40 [transform={m=((4.00,0.00)(0.00,4.00)) t=(30.00,115.00)}]
         LayoutSVGRect {rect} at (10,115) size 40x20 [fill={[type=SOLID] [color=#000000]}] [x=-5.00] [y=0.00] [width=10.00] [height=5.00]
         LayoutSVGRect {rect} at (10,135) size 40x20 [fill={[type=SOLID] [color=#FF0000]}] [x=-5.00] [y=5.00] [width=10.00] [height=5.00]
-      LayoutSVGText {text} at (60,185) size 336x19 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 336x19
+      LayoutSVGText {text} at (60,185) size 337x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 337x19
           chunk 1 text run 1 at (60.00,200.00) startOffset 0 endOffset 48 width 336.00: "Percentage width/height to user space conversion"
       LayoutSVGContainer {g} at (10,175) size 40x41 [transform={m=((4.00,0.00)(0.00,4.00)) t=(30.00,175.00)}]
         LayoutSVGRect {rect} at (10,175) size 40x20 [fill={[type=SOLID] [color=#000000]}] [x=-5.00] [y=0.00] [width=10.00] [height=5.00]
         LayoutSVGRect {rect} at (10,195) size 40x21 [fill={[type=SOLID] [color=#FF0000]}] [x=-5.00] [y=5.00] [width=10.00] [height=5.00]
-      LayoutSVGText {text} at (140,250) size 259x19 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 259x19
+      LayoutSVGText {text} at (140,250) size 260x19 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 260x19
           chunk 1 text run 1 at (140.00,265.00) startOffset 0 endOffset 36 width 259.00: "CSS and percentage length conversion"
       LayoutSVGContainer {g} at (0,244) size 146x32 [transform={m=((4.00,0.00)(4.00,4.00)) t=(30.00,260.00)}]
         LayoutSVGEllipse {circle} at (1,245) size 58x30 [fill={[type=SOLID] [color=#000000]}] [cx=0.00] [cy=0.00] [r=3.54]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png
index 7d9b7cd..9322f0f7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/hixie/perf/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/image-with-clip-path-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/image-with-clip-path-expected.txt
index f91bc5fd..dedf9d1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/image-with-clip-path-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/image-with-clip-path-expected.txt
@@ -91,6 +91,14 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGHiddenContainer defs",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGResourceClipper clipPath id='p'",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGRect rect id='r'",
       "reason": "full"
     },
@@ -107,6 +115,14 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGHiddenContainer defs",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGResourceClipper clipPath id='p'",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGRect rect id='r'",
       "reason": "full"
     },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/inner-svg-change-viewPort-relative-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/inner-svg-change-viewPort-relative-expected.txt
index 047290e..264832e4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/inner-svg-change-viewPort-relative-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/repaint/inner-svg-change-viewPort-relative-expected.txt
@@ -94,6 +94,14 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGHiddenContainer defs",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGPath polygon id='triangle'",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGRect rect",
       "reason": "full"
     },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt
index c3c206f..a5a2f3f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt
@@ -59,11 +59,6 @@
           "reason": "forced by layout"
         },
         {
-          "object": "LayoutSVGText text",
-          "rect": [0, 64, 193, 46],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutSVGInlineText #text",
           "rect": [0, 14, 193, 46],
           "reason": "bounds change"
@@ -124,11 +119,6 @@
           "reason": "bounds change"
         },
         {
-          "object": "LayoutSVGText text",
-          "rect": [310, 64, 92, 46],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutSVGInlineText #text",
           "rect": [310, 14, 92, 46],
           "reason": "bounds change"
@@ -286,30 +276,6 @@
       "reason": "full"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS '",
-      "reason": "full"
-    },
-    {
-      "object": "InlineFlowBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS'",
-      "reason": "full"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS'",
-      "reason": "full"
-    },
-    {
       "object": "LayoutSVGRoot (positioned) svg",
       "reason": "bounds change"
     },
@@ -399,19 +365,67 @@
     },
     {
       "object": "LayoutSVGText text",
-      "reason": "forced by layout"
+      "reason": "none"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "forced by layout"
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS '",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "none"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGForeignObject foreignObject",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutBlockFlow P",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGViewportContainer svg",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGText text",
-      "reason": "forced by layout"
+      "reason": "none"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "forced by layout"
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGContainer g id='text3g'",
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png
index bbf9fc80..45686dd0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
index e097055..6b11ca6 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
@@ -25,8 +25,8 @@
       LayoutSVGText {text} at (25,174) size 298x57 contains 1 chunk(s)
         LayoutSVGInlineText {#text} at (0,0) size 298x57
           chunk 1 text run 1 at (25.00,220.00) startOffset 0 endOffset 15 width 297.60: "Pattern on fill"
-      LayoutSVGText {text} at (25,223) size 213x16 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 213x16
+      LayoutSVGText {text} at (25,223) size 214x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 214x16
           chunk 1 text run 1 at (25.00,235.00) startOffset 0 endOffset 38 width 212.40: "Pattern consists of red and green rows"
       LayoutSVGResourcePattern {pattern} [id="pat4"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
         LayoutSVGRect {rect} at (0,0) size 8x12 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=10.00] [height=10.00]
@@ -34,8 +34,8 @@
       LayoutSVGText {text} at (25,237) size 292x47 contains 1 chunk(s)
         LayoutSVGInlineText {#text} at (0,0) size 292x46
           chunk 1 text run 1 at (25.00,275.00) startOffset 0 endOffset 17 width 291.60: "Pattern on stroke"
-      LayoutSVGText {text} at (25,278) size 230x16 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 230x16
+      LayoutSVGText {text} at (25,278) size 231x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 231x16
           chunk 1 text run 1 at (25.00,290.00) startOffset 0 endOffset 40 width 229.20: "Pattern consists of red and blue columns"
       LayoutSVGText {text} at (10,305) size 258x45 contains 1 chunk(s)
         LayoutSVGInlineText {#text} at (0,0) size 258x45
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
index d6de75899..27d0fac 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
@@ -196,7 +196,7 @@
             LayoutTableCell {TD} at (300,697) size 147x39 [r=17 c=2 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x36
                 text run at (1,1) width 65: "3-18"
-          LayoutTableRow {TR} at (0,738) size 449x47
+          LayoutTableRow {TR} at (0,738) size 449x39
             LayoutTableCell {TD} at (2,791) size 147x39 [r=18 c=0 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x36
                 text run at (1,1) width 65: "1-19"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/printing/thead-repeats-at-top-of-each-page-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/printing/thead-repeats-at-top-of-each-page-expected.txt
index 75f8df4..d78d4af2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/printing/thead-repeats-at-top-of-each-page-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/printing/thead-repeats-at-top-of-each-page-expected.txt
@@ -196,7 +196,7 @@
             LayoutTableCell {TD} at (302,697) size 148x39 [r=17 c=2 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x37
                 text run at (1,1) width 65: "3-18"
-          LayoutTableRow {TR} at (0,738) size 452x48
+          LayoutTableRow {TR} at (0,738) size 452x39
             LayoutTableCell {TD} at (2,791) size 148x39 [r=18 c=0 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x37
                 text run at (1,1) width 65: "1-19"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png
index 229c1bd..840a588 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/hixie/perf/006-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt
index dd8c571b..f3299fa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt
@@ -59,11 +59,6 @@
           "reason": "forced by layout"
         },
         {
-          "object": "LayoutSVGText text",
-          "rect": [0, 64, 194, 46],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutSVGInlineText #text",
           "rect": [0, 14, 194, 46],
           "reason": "bounds change"
@@ -124,11 +119,6 @@
           "reason": "bounds change"
         },
         {
-          "object": "LayoutSVGText text",
-          "rect": [310, 64, 92, 46],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutSVGInlineText #text",
           "rect": [310, 14, 92, 46],
           "reason": "bounds change"
@@ -326,30 +316,6 @@
       "reason": "full"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS '",
-      "reason": "full"
-    },
-    {
-      "object": "InlineFlowBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS'",
-      "reason": "full"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS'",
-      "reason": "full"
-    },
-    {
       "object": "LayoutSVGRoot (positioned) svg",
       "reason": "bounds change"
     },
@@ -439,19 +405,67 @@
     },
     {
       "object": "LayoutSVGText text",
-      "reason": "forced by layout"
+      "reason": "none"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "forced by layout"
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS '",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "none"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGForeignObject foreignObject",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutBlockFlow P",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGViewportContainer svg",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGText text",
-      "reason": "forced by layout"
+      "reason": "none"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "forced by layout"
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGContainer g id='text3g'",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png
index 48c9d1a3..f6685cb4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
index 75f8df4..d78d4af2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
@@ -196,7 +196,7 @@
             LayoutTableCell {TD} at (302,697) size 148x39 [r=17 c=2 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x37
                 text run at (1,1) width 65: "3-18"
-          LayoutTableRow {TR} at (0,738) size 452x48
+          LayoutTableRow {TR} at (0,738) size 452x39
             LayoutTableCell {TD} at (2,791) size 148x39 [r=18 c=0 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x37
                 text run at (1,1) width 65: "1-19"
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt
index 925e4926..0f6985b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt
@@ -59,11 +59,6 @@
           "reason": "forced by layout"
         },
         {
-          "object": "LayoutSVGText text",
-          "rect": [0, 64, 194, 45],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutSVGInlineText #text",
           "rect": [0, 14, 194, 45],
           "reason": "bounds change"
@@ -124,11 +119,6 @@
           "reason": "bounds change"
         },
         {
-          "object": "LayoutSVGText text",
-          "rect": [310, 64, 92, 45],
-          "reason": "forced by layout"
-        },
-        {
           "object": "LayoutSVGInlineText #text",
           "rect": [310, 14, 92, 45],
           "reason": "bounds change"
@@ -286,30 +276,6 @@
       "reason": "full"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS '",
-      "reason": "full"
-    },
-    {
-      "object": "InlineFlowBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS'",
-      "reason": "full"
-    },
-    {
-      "object": "RootInlineBox",
-      "reason": "full"
-    },
-    {
-      "object": "InlineTextBox 'PASS'",
-      "reason": "full"
-    },
-    {
       "object": "LayoutSVGRoot (positioned) svg",
       "reason": "bounds change"
     },
@@ -399,19 +365,67 @@
     },
     {
       "object": "LayoutSVGText text",
-      "reason": "forced by layout"
+      "reason": "none"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "forced by layout"
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS '",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGTSpan tspan",
+      "reason": "none"
+    },
+    {
+      "object": "InlineFlowBox",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGForeignObject foreignObject",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutBlockFlow P",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGViewportContainer svg",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGText text",
-      "reason": "forced by layout"
+      "reason": "none"
     },
     {
-      "object": "RootInlineBox",
-      "reason": "forced by layout"
+      "object": "LayoutSVGInlineText #text",
+      "reason": "none"
+    },
+    {
+      "object": "InlineTextBox 'PASS'",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGContainer g id='text3g'",
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png
index 4e4cd7c0..55f1b94 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
index 67affb0..01fa565b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/text-with-pattern-with-svg-transform-expected.txt
@@ -25,8 +25,8 @@
       LayoutSVGText {text} at (25,174) size 292x57 contains 1 chunk(s)
         LayoutSVGInlineText {#text} at (0,0) size 292x57
           chunk 1 text run 1 at (25.00,220.00) startOffset 0 endOffset 15 width 291.77: "Pattern on fill"
-      LayoutSVGText {text} at (25,223) size 212x16 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 212x16
+      LayoutSVGText {text} at (25,223) size 213x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 213x16
           chunk 1 text run 1 at (25.00,235.00) startOffset 0 endOffset 38 width 211.20: "Pattern consists of red and green rows"
       LayoutSVGResourcePattern {pattern} [id="pat4"] [patternUnits=objectBoundingBox] [patternContentUnits=userSpaceOnUse]
         LayoutSVGRect {rect} at (0,0) size 8x12 [fill={[type=SOLID] [color=#FF0000]}] [x=0.00] [y=0.00] [width=10.00] [height=10.00]
@@ -34,8 +34,8 @@
       LayoutSVGText {text} at (25,239) size 305x45 contains 1 chunk(s)
         LayoutSVGInlineText {#text} at (0,0) size 305x45
           chunk 1 text run 1 at (25.00,275.00) startOffset 0 endOffset 17 width 304.58: "Pattern on stroke"
-      LayoutSVGText {text} at (25,278) size 227x16 contains 1 chunk(s)
-        LayoutSVGInlineText {#text} at (0,0) size 227x16
+      LayoutSVGText {text} at (25,278) size 228x16 contains 1 chunk(s)
+        LayoutSVGInlineText {#text} at (0,0) size 228x16
           chunk 1 text run 1 at (25.00,290.00) startOffset 0 endOffset 40 width 226.80: "Pattern consists of red and blue columns"
       LayoutSVGText {text} at (10,304) size 264x45 contains 1 chunk(s)
         LayoutSVGInlineText {#text} at (0,0) size 264x45
diff --git a/third_party/WebKit/LayoutTests/platform/win7/printing/thead-repeats-at-top-of-each-page-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/printing/thead-repeats-at-top-of-each-page-expected.txt
index 486a834..40f6876 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/printing/thead-repeats-at-top-of-each-page-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win7/printing/thead-repeats-at-top-of-each-page-expected.txt
@@ -196,7 +196,7 @@
             LayoutTableCell {TD} at (302,697) size 148x39 [r=17 c=2 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x36
                 text run at (1,1) width 65: "3-18"
-          LayoutTableRow {TR} at (0,738) size 452x48
+          LayoutTableRow {TR} at (0,738) size 452x39
             LayoutTableCell {TD} at (2,791) size 148x39 [r=18 c=0 rs=1 cs=1]
               LayoutText {#text} at (1,1) size 65x36
                 text run at (1,1) width 65: "1-19"
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
new file mode 100644
index 0000000..40f6876
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/threaded/printing/thead-repeats-at-top-of-each-page-expected.txt
@@ -0,0 +1,368 @@
+layer at (0,0) size 1046x799 scrollHeight 1547
+  LayoutView at (0,0) size 1046x799
+layer at (0,0) size 1046x1547 backgroundClip at (0,0) size 1046x799 clip at (0,0) size 1046x799
+  LayoutBlockFlow {HTML} at (0,0) size 1046x1547
+    LayoutBlockFlow {BODY} at (8,8) size 1030x1531
+      LayoutTable {TABLE} at (0,0) size 452x1531
+        LayoutTableSection {THEAD} at (0,0) size 452x43
+          LayoutTableRow {TR} at (0,2) size 452x39
+            LayoutTableCell {TH} at (2,2) size 148x39 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 146x36
+                text run at (1,1) width 146: "Column 1"
+            LayoutTableCell {TH} at (152,2) size 148x39 [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 146x36
+                text run at (1,1) width 146: "Column 2"
+            LayoutTableCell {TH} at (302,2) size 148x39 [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 146x36
+                text run at (1,1) width 146: "Column 3"
+        LayoutTableSection {TBODY} at (0,43) size 452x1488
+          LayoutTableRow {TR} at (0,0) size 452x39
+            LayoutTableCell {TD} at (2,0) size 148x39 [r=0 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-1"
+            LayoutTableCell {TD} at (152,0) size 148x39 [r=0 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-1"
+            LayoutTableCell {TD} at (302,0) size 148x39 [r=0 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-1"
+          LayoutTableRow {TR} at (0,41) size 452x39
+            LayoutTableCell {TD} at (2,41) size 148x39 [r=1 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-2"
+            LayoutTableCell {TD} at (152,41) size 148x39 [r=1 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-2"
+            LayoutTableCell {TD} at (302,41) size 148x39 [r=1 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-2"
+          LayoutTableRow {TR} at (0,82) size 452x39
+            LayoutTableCell {TD} at (2,82) size 148x39 [r=2 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-3"
+            LayoutTableCell {TD} at (152,82) size 148x39 [r=2 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-3"
+            LayoutTableCell {TD} at (302,82) size 148x39 [r=2 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-3"
+          LayoutTableRow {TR} at (0,123) size 452x39
+            LayoutTableCell {TD} at (2,123) size 148x39 [r=3 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-4"
+            LayoutTableCell {TD} at (152,123) size 148x39 [r=3 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-4"
+            LayoutTableCell {TD} at (302,123) size 148x39 [r=3 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-4"
+          LayoutTableRow {TR} at (0,164) size 452x39
+            LayoutTableCell {TD} at (2,164) size 148x39 [r=4 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-5"
+            LayoutTableCell {TD} at (152,164) size 148x39 [r=4 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-5"
+            LayoutTableCell {TD} at (302,164) size 148x39 [r=4 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-5"
+          LayoutTableRow {TR} at (0,205) size 452x39
+            LayoutTableCell {TD} at (2,205) size 148x39 [r=5 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-6"
+            LayoutTableCell {TD} at (152,205) size 148x39 [r=5 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-6"
+            LayoutTableCell {TD} at (302,205) size 148x39 [r=5 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-6"
+          LayoutTableRow {TR} at (0,246) size 452x39
+            LayoutTableCell {TD} at (2,246) size 148x39 [r=6 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-7"
+            LayoutTableCell {TD} at (152,246) size 148x39 [r=6 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-7"
+            LayoutTableCell {TD} at (302,246) size 148x39 [r=6 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-7"
+          LayoutTableRow {TR} at (0,287) size 452x39
+            LayoutTableCell {TD} at (2,287) size 148x39 [r=7 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-8"
+            LayoutTableCell {TD} at (152,287) size 148x39 [r=7 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-8"
+            LayoutTableCell {TD} at (302,287) size 148x39 [r=7 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-8"
+          LayoutTableRow {TR} at (0,328) size 452x39
+            LayoutTableCell {TD} at (2,328) size 148x39 [r=8 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "1-9"
+            LayoutTableCell {TD} at (152,328) size 148x39 [r=8 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "2-9"
+            LayoutTableCell {TD} at (302,328) size 148x39 [r=8 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 47x36
+                text run at (1,1) width 47: "3-9"
+          LayoutTableRow {TR} at (0,369) size 452x39
+            LayoutTableCell {TD} at (2,369) size 148x39 [r=9 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-10"
+            LayoutTableCell {TD} at (152,369) size 148x39 [r=9 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-10"
+            LayoutTableCell {TD} at (302,369) size 148x39 [r=9 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-10"
+          LayoutTableRow {TR} at (0,410) size 452x39
+            LayoutTableCell {TD} at (2,410) size 148x39 [r=10 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 62x36
+                text run at (1,1) width 62: "1-11"
+            LayoutTableCell {TD} at (152,410) size 148x39 [r=10 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 62x36
+                text run at (1,1) width 62: "2-11"
+            LayoutTableCell {TD} at (302,410) size 148x39 [r=10 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 62x36
+                text run at (1,1) width 62: "3-11"
+          LayoutTableRow {TR} at (0,451) size 452x39
+            LayoutTableCell {TD} at (2,451) size 148x39 [r=11 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-12"
+            LayoutTableCell {TD} at (152,451) size 148x39 [r=11 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-12"
+            LayoutTableCell {TD} at (302,451) size 148x39 [r=11 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-12"
+          LayoutTableRow {TR} at (0,492) size 452x39
+            LayoutTableCell {TD} at (2,492) size 148x39 [r=12 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-13"
+            LayoutTableCell {TD} at (152,492) size 148x39 [r=12 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-13"
+            LayoutTableCell {TD} at (302,492) size 148x39 [r=12 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-13"
+          LayoutTableRow {TR} at (0,533) size 452x39
+            LayoutTableCell {TD} at (2,533) size 148x39 [r=13 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-14"
+            LayoutTableCell {TD} at (152,533) size 148x39 [r=13 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-14"
+            LayoutTableCell {TD} at (302,533) size 148x39 [r=13 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-14"
+          LayoutTableRow {TR} at (0,574) size 452x39
+            LayoutTableCell {TD} at (2,574) size 148x39 [r=14 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-15"
+            LayoutTableCell {TD} at (152,574) size 148x39 [r=14 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-15"
+            LayoutTableCell {TD} at (302,574) size 148x39 [r=14 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-15"
+          LayoutTableRow {TR} at (0,615) size 452x39
+            LayoutTableCell {TD} at (2,615) size 148x39 [r=15 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-16"
+            LayoutTableCell {TD} at (152,615) size 148x39 [r=15 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-16"
+            LayoutTableCell {TD} at (302,615) size 148x39 [r=15 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-16"
+          LayoutTableRow {TR} at (0,656) size 452x39
+            LayoutTableCell {TD} at (2,656) size 148x39 [r=16 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-17"
+            LayoutTableCell {TD} at (152,656) size 148x39 [r=16 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-17"
+            LayoutTableCell {TD} at (302,656) size 148x39 [r=16 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-17"
+          LayoutTableRow {TR} at (0,697) size 452x39
+            LayoutTableCell {TD} at (2,697) size 148x39 [r=17 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-18"
+            LayoutTableCell {TD} at (152,697) size 148x39 [r=17 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-18"
+            LayoutTableCell {TD} at (302,697) size 148x39 [r=17 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-18"
+          LayoutTableRow {TR} at (0,738) size 452x39
+            LayoutTableCell {TD} at (2,791) size 148x39 [r=18 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-19"
+            LayoutTableCell {TD} at (152,791) size 148x39 [r=18 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-19"
+            LayoutTableCell {TD} at (302,791) size 148x39 [r=18 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-19"
+          LayoutTableRow {TR} at (0,832) size 452x39
+            LayoutTableCell {TD} at (2,832) size 148x39 [r=19 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-20"
+            LayoutTableCell {TD} at (152,832) size 148x39 [r=19 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-20"
+            LayoutTableCell {TD} at (302,832) size 148x39 [r=19 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-20"
+          LayoutTableRow {TR} at (0,873) size 452x39
+            LayoutTableCell {TD} at (2,873) size 148x39 [r=20 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-21"
+            LayoutTableCell {TD} at (152,873) size 148x39 [r=20 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-21"
+            LayoutTableCell {TD} at (302,873) size 148x39 [r=20 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-21"
+          LayoutTableRow {TR} at (0,914) size 452x39
+            LayoutTableCell {TD} at (2,914) size 148x39 [r=21 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-22"
+            LayoutTableCell {TD} at (152,914) size 148x39 [r=21 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-22"
+            LayoutTableCell {TD} at (302,914) size 148x39 [r=21 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-22"
+          LayoutTableRow {TR} at (0,955) size 452x39
+            LayoutTableCell {TD} at (2,955) size 148x39 [r=22 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-23"
+            LayoutTableCell {TD} at (152,955) size 148x39 [r=22 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-23"
+            LayoutTableCell {TD} at (302,955) size 148x39 [r=22 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-23"
+          LayoutTableRow {TR} at (0,996) size 452x39
+            LayoutTableCell {TD} at (2,996) size 148x39 [r=23 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-24"
+            LayoutTableCell {TD} at (152,996) size 148x39 [r=23 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-24"
+            LayoutTableCell {TD} at (302,996) size 148x39 [r=23 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-24"
+          LayoutTableRow {TR} at (0,1037) size 452x39
+            LayoutTableCell {TD} at (2,1037) size 148x39 [r=24 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-25"
+            LayoutTableCell {TD} at (152,1037) size 148x39 [r=24 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-25"
+            LayoutTableCell {TD} at (302,1037) size 148x39 [r=24 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-25"
+          LayoutTableRow {TR} at (0,1078) size 452x39
+            LayoutTableCell {TD} at (2,1078) size 148x39 [r=25 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-26"
+            LayoutTableCell {TD} at (152,1078) size 148x39 [r=25 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-26"
+            LayoutTableCell {TD} at (302,1078) size 148x39 [r=25 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-26"
+          LayoutTableRow {TR} at (0,1119) size 452x39
+            LayoutTableCell {TD} at (2,1119) size 148x39 [r=26 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-27"
+            LayoutTableCell {TD} at (152,1119) size 148x39 [r=26 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-27"
+            LayoutTableCell {TD} at (302,1119) size 148x39 [r=26 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-27"
+          LayoutTableRow {TR} at (0,1160) size 452x39
+            LayoutTableCell {TD} at (2,1160) size 148x39 [r=27 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-28"
+            LayoutTableCell {TD} at (152,1160) size 148x39 [r=27 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-28"
+            LayoutTableCell {TD} at (302,1160) size 148x39 [r=27 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-28"
+          LayoutTableRow {TR} at (0,1201) size 452x39
+            LayoutTableCell {TD} at (2,1201) size 148x39 [r=28 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-29"
+            LayoutTableCell {TD} at (152,1201) size 148x39 [r=28 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-29"
+            LayoutTableCell {TD} at (302,1201) size 148x39 [r=28 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-29"
+          LayoutTableRow {TR} at (0,1242) size 452x39
+            LayoutTableCell {TD} at (2,1242) size 148x39 [r=29 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-30"
+            LayoutTableCell {TD} at (152,1242) size 148x39 [r=29 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-30"
+            LayoutTableCell {TD} at (302,1242) size 148x39 [r=29 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-30"
+          LayoutTableRow {TR} at (0,1283) size 452x39
+            LayoutTableCell {TD} at (2,1283) size 148x39 [r=30 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-31"
+            LayoutTableCell {TD} at (152,1283) size 148x39 [r=30 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-31"
+            LayoutTableCell {TD} at (302,1283) size 148x39 [r=30 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-31"
+          LayoutTableRow {TR} at (0,1324) size 452x39
+            LayoutTableCell {TD} at (2,1324) size 148x39 [r=31 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-32"
+            LayoutTableCell {TD} at (152,1324) size 148x39 [r=31 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-32"
+            LayoutTableCell {TD} at (302,1324) size 148x39 [r=31 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-32"
+          LayoutTableRow {TR} at (0,1365) size 452x39
+            LayoutTableCell {TD} at (2,1365) size 148x39 [r=32 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-33"
+            LayoutTableCell {TD} at (152,1365) size 148x39 [r=32 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-33"
+            LayoutTableCell {TD} at (302,1365) size 148x39 [r=32 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-33"
+          LayoutTableRow {TR} at (0,1406) size 452x39
+            LayoutTableCell {TD} at (2,1406) size 148x39 [r=33 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-34"
+            LayoutTableCell {TD} at (152,1406) size 148x39 [r=33 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-34"
+            LayoutTableCell {TD} at (302,1406) size 148x39 [r=33 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-34"
+          LayoutTableRow {TR} at (0,1447) size 452x39
+            LayoutTableCell {TD} at (2,1447) size 148x39 [r=34 c=0 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "1-35"
+            LayoutTableCell {TD} at (152,1447) size 148x39 [r=34 c=1 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "2-35"
+            LayoutTableCell {TD} at (302,1447) size 148x39 [r=34 c=2 rs=1 cs=1]
+              LayoutText {#text} at (1,1) size 65x36
+                text run at (1,1) width 65: "3-35"
diff --git a/third_party/WebKit/LayoutTests/svg/custom/resource-client-removal-expected.txt b/third_party/WebKit/LayoutTests/svg/custom/resource-client-removal-expected.txt
index 4a1fb26f..377a16ac 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/resource-client-removal-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/custom/resource-client-removal-expected.txt
@@ -233,40 +233,8 @@
       "reason": "full"
     },
     {
-      "object": "LayoutSVGPath path id='hp'",
-      "reason": "SVG resource change"
-    },
-    {
-      "object": "LayoutSVGContainer g id='inneruse'",
-      "reason": "layoutObject insertion"
-    },
-    {
-      "object": "LayoutSVGContainer g",
-      "reason": "layoutObject insertion"
-    },
-    {
-      "object": "LayoutSVGPath path id='hp'",
-      "reason": "layoutObject insertion"
-    },
-    {
-      "object": "LayoutSVGPath path id='hp'",
-      "reason": "layoutObject removal"
-    },
-    {
-      "object": "LayoutSVGContainer g",
-      "reason": "layoutObject removal"
-    },
-    {
-      "object": "LayoutSVGContainer g id='inneruse'",
-      "reason": "layoutObject removal"
-    },
-    {
-      "object": "LayoutSVGGradientStop stop id='offset'",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutSVGContainer g id='inneruse'",
-      "reason": "full"
+      "object": "LayoutSVGContainer use",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGPath path id='hp'",
@@ -305,40 +273,8 @@
       "reason": "full"
     },
     {
-      "object": "LayoutSVGPath path id='hp'",
-      "reason": "SVG resource change"
-    },
-    {
-      "object": "LayoutSVGContainer g id='inneruse'",
-      "reason": "layoutObject insertion"
-    },
-    {
-      "object": "LayoutSVGContainer g",
-      "reason": "layoutObject insertion"
-    },
-    {
-      "object": "LayoutSVGPath path id='hp'",
-      "reason": "layoutObject insertion"
-    },
-    {
-      "object": "LayoutSVGPath path id='hp'",
-      "reason": "layoutObject removal"
-    },
-    {
-      "object": "LayoutSVGContainer g",
-      "reason": "layoutObject removal"
-    },
-    {
-      "object": "LayoutSVGContainer g id='inneruse'",
-      "reason": "layoutObject removal"
-    },
-    {
-      "object": "LayoutSVGGradientStop stop id='offset'",
-      "reason": "full"
-    },
-    {
-      "object": "LayoutSVGContainer g id='inneruse'",
-      "reason": "full"
+      "object": "LayoutSVGContainer use",
+      "reason": "none"
     },
     {
       "object": "LayoutSVGPath path id='hp'",
@@ -377,6 +313,90 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGContainer use",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGPath path id='hp'",
+      "reason": "SVG resource change"
+    },
+    {
+      "object": "LayoutSVGContainer g id='inneruse'",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "LayoutSVGContainer g",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "LayoutSVGPath path id='hp'",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "LayoutSVGPath path id='hp'",
+      "reason": "layoutObject removal"
+    },
+    {
+      "object": "LayoutSVGContainer g",
+      "reason": "layoutObject removal"
+    },
+    {
+      "object": "LayoutSVGContainer g id='inneruse'",
+      "reason": "layoutObject removal"
+    },
+    {
+      "object": "LayoutSVGGradientStop stop id='offset'",
+      "reason": "full"
+    },
+    {
+      "object": "LayoutSVGContainer g id='inneruse'",
+      "reason": "full"
+    },
+    {
+      "object": "LayoutSVGContainer use",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGPath path id='hp'",
+      "reason": "SVG resource change"
+    },
+    {
+      "object": "LayoutSVGContainer g id='inneruse'",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "LayoutSVGContainer g",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "LayoutSVGPath path id='hp'",
+      "reason": "layoutObject insertion"
+    },
+    {
+      "object": "LayoutSVGPath path id='hp'",
+      "reason": "layoutObject removal"
+    },
+    {
+      "object": "LayoutSVGContainer g",
+      "reason": "layoutObject removal"
+    },
+    {
+      "object": "LayoutSVGContainer g id='inneruse'",
+      "reason": "layoutObject removal"
+    },
+    {
+      "object": "LayoutSVGGradientStop stop id='offset'",
+      "reason": "full"
+    },
+    {
+      "object": "LayoutSVGContainer g id='inneruse'",
+      "reason": "full"
+    },
+    {
+      "object": "LayoutSVGContainer use",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGPath path id='hp'",
       "reason": "SVG resource change"
     },
diff --git a/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt b/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt
index e7d157b5..bfa0121 100644
--- a/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/dom/length-list-parser-expected.txt
@@ -1,238 +1,238 @@
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e,-.e+968,52e,78-.,e809423-e7\t,8695e3"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0e-8"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 072"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="84e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t73+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="010--613506-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1,.,+.833+.004 2-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+.9-\t8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.7980-555-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-198\t50"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3.3+945-.+.5,6-19 ,666,+1+-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161ee002+3+5"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1e, -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017e0-342114,6\t879-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018e5.\t+0e 10+ -719.e75"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="9-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\t0,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e4-5,6e5-28026,66-1 6 1e8-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000161 -0 8,1 7+0,573 0\te,9ee\t2+5e,-.e+968,52e,78-.,e809423-e7\t,8695e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e7e+ -27e\t\t3-20256803-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="564281 0ee51+ e \t378584833\t,.141\te8-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-53. 88530-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010\t8.-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018.847e28886-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014e85 .-1-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001608\t9 367 ..81e9e539\te 4 e-17 6911-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e88. 965---39 0"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="-8e8625686 3.0-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001, 90,e4997..,782-4326e.\t-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013e,+e9\te 4829.,063721-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e6 07238"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="e-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 362+-.1+1e0 4 4e 28\t-8 -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,47"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="04,-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001993,35\t+684 +\t159e   +.3-e0+,812-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001728-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014+,--1-26e666460-79.5-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000169603-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010641,,572-960\t1-9 289\t"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="3+.47e19353 2+\t77+6 ,-+47 ,7428.6ee52.9  .-e6"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-.e1"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="61822,15-00.166.7 "
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="2\t.5,658-7 e ,8477553"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="7-3469.43,+,0\t 1-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015181-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001. -869+.. +31\t8,514\t0. 8 e37e"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000147322\t6\t\t2 50635- 385\t5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001949,-"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="8 2 589\t-45e58 -4\t-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e58-++689.-98-,42 94564.,967-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011+ ,9+6-\t.765+-87 e. 68\t9452182-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016.. 1\t+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="1+.5-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+7+"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="+08-14\t4- .57-\t -0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017+ -1-.0e+7-1--0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001+\te.96-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,488e16414,,.+ 15"
-CONSOLE ERROR: Error: Invalid value for <text> attribute x="\u0000"
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e,-.e+968,52e,78…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7e+ -27e\t\t3-2025…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "28886-0.00000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8625686 3.0-0.0000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "84e-0.0000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "79.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "010--613506-0.00…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1,.,+.833+.004 2-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3.3+945-.+.5,6-1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1e, -0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "9-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e7e+ -27e\t\t3-202…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "564281 0ee51+ e \t378584…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…000001608\t9 367 ..81e9e539\te 4 e…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "-8e8625686 3.0-0…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "e-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "…0001993,35\t+684 +\t159e   +.3-e0+…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "3+.47e19353 2+\t7…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "--0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "61822,15-00.166.7 ".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "2\t.5,658-7 e ,8477553".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "7-3469.43,+,0\t 1…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1-0.000000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "8 2 589\t-45e58 -4\t-0.000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "1+.5-0.000000000…".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "+08-14\t4- .57-\t …".
+CONSOLE ERROR: line 37: Error: <text> attribute x: Expected length, "\u0000".
 This test fuzzes the length list parser with semi-random attribute values and dumps the results of any values that parse successfully.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/svg/repaint/image-with-clip-path-expected.txt b/third_party/WebKit/LayoutTests/svg/repaint/image-with-clip-path-expected.txt
index 1c4951c..fdb2412 100644
--- a/third_party/WebKit/LayoutTests/svg/repaint/image-with-clip-path-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/repaint/image-with-clip-path-expected.txt
@@ -86,6 +86,14 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGHiddenContainer defs",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGResourceClipper clipPath id='p'",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGRect rect id='r'",
       "reason": "full"
     },
@@ -102,6 +110,14 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGHiddenContainer defs",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGResourceClipper clipPath id='p'",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGRect rect id='r'",
       "reason": "full"
     },
diff --git a/third_party/WebKit/LayoutTests/svg/repaint/inner-svg-change-viewPort-relative-expected.txt b/third_party/WebKit/LayoutTests/svg/repaint/inner-svg-change-viewPort-relative-expected.txt
index 502c8d4..209329e 100644
--- a/third_party/WebKit/LayoutTests/svg/repaint/inner-svg-change-viewPort-relative-expected.txt
+++ b/third_party/WebKit/LayoutTests/svg/repaint/inner-svg-change-viewPort-relative-expected.txt
@@ -94,6 +94,14 @@
       "reason": "full"
     },
     {
+      "object": "LayoutSVGHiddenContainer defs",
+      "reason": "none"
+    },
+    {
+      "object": "LayoutSVGPath polygon id='triangle'",
+      "reason": "none"
+    },
+    {
       "object": "LayoutSVGRect rect",
       "reason": "full"
     },
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
index 40a6326e..3c6dee4d 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.cpp
@@ -138,7 +138,7 @@
         worlds.append(it->value);
 }
 
-void DOMWrapperWorld::markWrappersInAllWorlds(ScriptWrappable* scriptWrappable, v8::Isolate* isolate)
+void DOMWrapperWorld::markWrappersInAllWorlds(ScriptWrappable* scriptWrappable, const WrapperVisitor* visitor)
 {
     // TODO(hlopko): Currently wrapper in one world will keep wrappers in all
     // worlds alive (possibly holding on entire documents). This is neither
@@ -146,7 +146,7 @@
     // (big performance and memory overhead).
 
     // Marking for the main world
-    scriptWrappable->markWrapper(isolate);
+    scriptWrappable->markWrapper(visitor);
     if (!isMainThread())
         return;
     WorldMap& isolatedWorlds = isolatedWorldMap();
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
index ae73701..fefc8fa 100644
--- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
+++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorld.h
@@ -71,7 +71,7 @@
 
     static bool isolatedWorldsExist() { return isolatedWorldCount; }
     static void allWorldsInMainThread(Vector<RefPtr<DOMWrapperWorld>>& worlds);
-    static void markWrappersInAllWorlds(ScriptWrappable*, v8::Isolate*);
+    static void markWrappersInAllWorlds(ScriptWrappable*, const WrapperVisitor*);
     static void setWrapperReferencesInAllWorlds(const v8::Persistent<v8::Object>& parent, ScriptWrappable*, v8::Isolate*);
 
     static DOMWrapperWorld& world(v8::Local<v8::Context> context)
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
index b06ec4f..3176f4f 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
@@ -212,7 +212,7 @@
         std::unique_ptr<Message>& message = m_reportedAsErrors.at(i);
         if (!message->isCollected() && message->hasPromise(data.GetPromise())) {
             message->makePromiseStrong();
-            Platform::current()->currentThread()->scheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, WTF::bind(&RejectedPromises::revokeNow, this, passed(std::move(message))));
+            Platform::current()->currentThread()->scheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, WTF::bind(&RejectedPromises::revokeNow, RefPtr<RejectedPromises>(this), passed(std::move(message))));
             m_reportedAsErrors.remove(i);
             return;
         }
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.cpp
index abd07aa..fe38dab 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.cpp
@@ -36,10 +36,10 @@
     return V8DOMWrapper::associateObjectWithWrapper(isolate, this, wrapperTypeInfo, wrapper);
 }
 
-void ScriptWrappable::markWrapper(v8::Isolate* isolate) const
+void ScriptWrappable::markWrapper(const WrapperVisitor* visitor) const
 {
     if (containsWrapper())
-        ScriptWrappableVisitor::markWrapper(&m_mainWorldWrapper, isolate);
+        visitor->markWrapper(&m_mainWorldWrapper);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h
index ee6e9858..b1305ca 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappable.h
@@ -149,7 +149,7 @@
      *  wrapper in the main world. To mark wrappers in all worlds call
      *  ScriptWrappableVisitor::markWrapper(ScriptWrappable*, v8::Isolate*)
      */
-    void markWrapper(v8::Isolate*) const;
+    void markWrapper(const WrapperVisitor*) const;
 
     DECLARE_VIRTUAL_TRACE_WRAPPERS() {};
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
index fe867840..dd674b0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
@@ -6,6 +6,7 @@
 
 #include "bindings/core/v8/ActiveScriptWrappable.h"
 #include "bindings/core/v8/DOMWrapperWorld.h"
+#include "bindings/core/v8/V8AbstractEventListener.h"
 #include "bindings/core/v8/WrapperTypeInfo.h"
 #include "core/dom/DocumentStyleSheetCollection.h"
 #include "core/dom/ElementRareData.h"
@@ -109,13 +110,27 @@
 
 void ScriptWrappableVisitor::markWrappersInAllWorlds(const ScriptWrappable* scriptWrappable) const
 {
-    DOMWrapperWorld::markWrappersInAllWorlds(const_cast<ScriptWrappable*>(scriptWrappable), m_isolate);
+    DOMWrapperWorld::markWrappersInAllWorlds(const_cast<ScriptWrappable*>(scriptWrappable), this);
 }
 
 void ScriptWrappableVisitor::traceWrappers(const ScopedPersistent<v8::Value>* scopedPersistent) const
 {
-    markWrapper(
-        &(const_cast<ScopedPersistent<v8::Value>*>(scopedPersistent)->get()));
+    markWrapper(&(const_cast<ScopedPersistent<v8::Value>*>(scopedPersistent)->get()));
+}
+
+void ScriptWrappableVisitor::traceWrappers(const ScopedPersistent<v8::Object>* scopedPersistent) const
+{
+    markWrapper(&(const_cast<ScopedPersistent<v8::Object>*>(scopedPersistent)->get()));
+}
+
+void ScriptWrappableVisitor::markWrapper(const v8::PersistentBase<v8::Value>* handle) const
+{
+    handle->RegisterExternalReference(m_isolate);
+}
+
+void ScriptWrappableVisitor::markWrapper(const v8::PersistentBase<v8::Object>* handle) const
+{
+    handle->RegisterExternalReference(m_isolate);
 }
 
 void ScriptWrappableVisitor::dispatchTraceWrappers(const ScriptWrappable* wrappable) const
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
index 59eabbb7..fce3cedc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.h
@@ -83,14 +83,6 @@
      * gc.
      */
     static void invalidateDeadObjectsInMarkingDeque(v8::Isolate*);
-    /**
-     * Mark given wrapper as alive in V8.
-     */
-    template <typename T>
-    static void markWrapper(const v8::Persistent<T>* handle, v8::Isolate* isolate)
-    {
-        handle->RegisterExternalReference(isolate);
-    }
 
     void TracePrologue() override;
     void RegisterV8References(const std::vector<std::pair<void*, void*>>& internalFieldsOfPotentialWrappers) override;
@@ -100,12 +92,6 @@
     void AbortTracing() override;
     void EnterFinalPause() override;
 
-    template <typename T>
-    void markWrapper(const v8::Persistent<T>* handle) const
-    {
-        markWrapper(handle, m_isolate);
-    }
-
     void dispatchTraceWrappers(const ScriptWrappable*) const override;
 #define DECLARE_DISPATCH_TRACE_WRAPPERS(className)                   \
     void dispatchTraceWrappers(const className*) const override;
@@ -116,6 +102,9 @@
     void dispatchTraceWrappers(const void*) const override {}
 
     void traceWrappers(const ScopedPersistent<v8::Value>*) const override;
+    void traceWrappers(const ScopedPersistent<v8::Object>*) const override;
+    void markWrapper(const v8::PersistentBase<v8::Value>* handle) const;
+    void markWrapper(const v8::PersistentBase<v8::Object>* handle) const override;
 
     void invalidateDeadObjectsInMarkingDeque();
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp b/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp
index c499b7c9..f09ab370 100644
--- a/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/ToV8.cpp
@@ -20,12 +20,17 @@
 
     if (UNLIKELY(!window))
         return v8::Null(isolate);
-    // Initializes environment of a frame, and return the global object
-    // of the frame.
-    Frame * frame = window->frame();
-    if (!frame)
+
+    // TODO(yukishiino): There must be no case to return undefined.
+    // 'window', 'frames' and 'self' attributes in Window interface return
+    // the WindowProxy object of the browsing context, which never be undefined.
+    // 'top' and 'parent' attributes return the same when detached.  Therefore,
+    // there must be no case to return undefined.
+    // See http://crbug.com/621730 and http://crbug.com/621577 .
+    if (!window->isCurrentlyDisplayedInFrame())
         return v8Undefined();
 
+    Frame* frame = window->frame();
     return frame->windowProxy(DOMWrapperWorld::current(isolate))->globalIfNotDetached();
 }
 
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
index 714eea4..5da2531c 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.cpp
@@ -206,4 +206,9 @@
     EventListener::trace(visitor);
 }
 
+DEFINE_TRACE_WRAPPERS(V8AbstractEventListener)
+{
+    visitor->traceWrappers(&m_listener);
+}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h
index fe9eca7..d79f275 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h
@@ -108,6 +108,8 @@
 
     DECLARE_VIRTUAL_TRACE();
 
+    DECLARE_VIRTUAL_TRACE_WRAPPERS();
+
 protected:
     V8AbstractEventListener(bool isAttribute, DOMWrapperWorld&, v8::Isolate*);
 
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
index 26fe2ec..f67c1a9e 100644
--- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
+++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
@@ -20,7 +20,8 @@
 #include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/inspector/ConsoleMessage.h"
-#include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutAPIShim.h"
+#include "core/layout/api/LayoutViewItem.h"
 #include "core/timing/DOMWindowPerformance.h"
 #include "core/timing/Performance.h"
 #include "platform/Timer.h"
@@ -168,7 +169,7 @@
 {
     Node* node = rootNode();
     if (node->isDocumentNode())
-        return toDocument(node)->layoutView();
+        return LayoutAPIShim::layoutObjectFrom(toDocument(node)->layoutViewItem());
     return toElement(node)->layoutObject();
 }
 
diff --git a/third_party/WebKit/Source/core/events/EventTarget.cpp b/third_party/WebKit/Source/core/events/EventTarget.cpp
index a7115074..eebbc970 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.cpp
+++ b/third_party/WebKit/Source/core/events/EventTarget.cpp
@@ -141,9 +141,7 @@
         if (!v8listener->hasExistingListenerObject())
             continue;
 
-        ScriptWrappableVisitor::markWrapper(
-            &(v8listener->existingListenerObjectPersistentHandle()),
-            v8listener->isolate());
+        visitor->traceWrappers(v8listener);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
index e871c8e..233d4e4 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.cpp
@@ -103,7 +103,10 @@
 
 DOMWindow* DOMWindow::parent() const
 {
-    if (!frame())
+    // TODO(yukishiino): The 'parent' attribute must return |this|
+    // (the WindowProxy object of the browsing context itself) when it's
+    // top-level or detached.
+    if (!isCurrentlyDisplayedInFrame())
         return nullptr;
 
     Frame* parent = frame()->tree().parent();
@@ -112,7 +115,10 @@
 
 DOMWindow* DOMWindow::top() const
 {
-    if (!frame())
+    // TODO(yukishiino): The 'top' attribute must return |this|
+    // (the WindowProxy object of the browsing context itself) when it's
+    // top-level or detached.
+    if (!isCurrentlyDisplayedInFrame())
         return nullptr;
 
     return frame()->tree().top()->domWindow();
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index c6270646..8d5ca6d 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -955,27 +955,34 @@
 
     Document* document = m_frame->document();
 
-    // If the layout view was marked as needing layout after we added items in the subtree roots we need
-    // to clear the roots and do the layout from the layoutView.
-    if (layoutViewItem().needsLayout())
-        clearLayoutSubtreeRootsAndMarkContainingBlocks();
-    layoutViewItem().clearHitTestCache();
-
-    bool inSubtreeLayout = isSubtreeLayout();
-
-    // FIXME: The notion of a single root for layout is no longer applicable. Remove or update this code. crbug.com/460596
-    LayoutItem rootForThisLayout(inSubtreeLayout ? m_layoutSubtreeRootList.randomRoot() : layoutView());
-    if (!rootForThisLayout) {
-        // FIXME: Do we need to set m_size here?
-        ASSERT_NOT_REACHED();
-        return;
-    }
+    // TODO(crbug.com/460956): The notion of a single root for layout is no longer applicable. Remove or update this code.
+    LayoutObject* rootForThisLayout = layoutView();
 
     FontCachePurgePreventer fontCachePurgePreventer;
     {
         TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
-
         m_nestedLayoutCount++;
+
+        updateCounters();
+
+        // If the layout view was marked as needing layout after we added items in the subtree roots we need
+        // to clear the roots and do the layout from the layoutView.
+        if (layoutViewItem().needsLayout())
+            clearLayoutSubtreeRootsAndMarkContainingBlocks();
+        layoutViewItem().clearHitTestCache();
+
+        bool inSubtreeLayout = isSubtreeLayout();
+
+        // TODO(crbug.com/460956): The notion of a single root for layout is no longer applicable. Remove or update this code.
+        if (inSubtreeLayout)
+            rootForThisLayout = m_layoutSubtreeRootList.randomRoot();
+
+        if (!rootForThisLayout) {
+            // FIXME: Do we need to set m_size here?
+            NOTREACHED();
+            return;
+        }
+
         if (!inSubtreeLayout) {
             clearLayoutSubtreeRootsAndMarkContainingBlocks();
             Node* body = document->body();
@@ -987,10 +994,7 @@
                         body->layoutObject()->setChildNeedsLayout();
                 }
             }
-        }
-        updateCounters();
 
-        if (!inSubtreeLayout) {
             ScrollbarMode hMode;
             ScrollbarMode vMode;
             calculateScrollbarModes(hMode, vMode);
@@ -1045,14 +1049,13 @@
 
         performLayout(inSubtreeLayout);
 
+        if (!inSubtreeLayout && !document->printing())
+            adjustViewSizeAndLayout();
+
         ASSERT(m_layoutSubtreeRootList.isEmpty());
     } // Reset m_layoutSchedulingEnabled to its previous value.
     checkDoesNotNeedLayout();
 
-    if (!inSubtreeLayout && !document->printing())
-        adjustViewSizeAndLayout();
-    checkDoesNotNeedLayout();
-
     m_frameTimingRequestsDirty = true;
 
     // FIXME: Could find the common ancestor layer of all dirty subtrees and mark from there. crbug.com/462719
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
index 8bb45280b..32a7738 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -111,8 +111,8 @@
     {
         if (m_draggedNode && m_draggedNode->layoutObject())
             m_draggedNode->layoutObject()->updateDragState(true);
-        float deviceScaleFactor = m_localFrame->host()->chromeClient().screenInfo().deviceScaleFactor;
-
+        // TODO(oshima): Remove this when all platforms are migrated to use-zoom-for-dsf.
+        float deviceScaleFactor = m_localFrame->host()->deviceScaleFactorDeprecated();
         m_bounds.setWidth(m_bounds.width() * deviceScaleFactor);
         m_bounds.setHeight(m_bounds.height() * deviceScaleFactor);
         m_pictureBuilder = wrapUnique(new SkPictureBuilder(SkRect::MakeIWH(m_bounds.width(), m_bounds.height())));
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h
index a75982d..4bf9f33 100644
--- a/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1078,7 +1078,7 @@
         ImageDocument = 1274,
         ScriptPassesCSPDynamic = 1275,
         ScriptPassesCSPNonce = 1276,
-        CSPWithUnsafeDynamic = 1277,
+        CSPWithStrictDynamic = 1277,
         ScrollAnchored = 1278,
         AddEventListenerFourArguments = 1279,
         RemoveEventListenerFourArguments = 1280,
diff --git a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
index 643530e..addd65a 100644
--- a/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
+++ b/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -203,7 +203,7 @@
             UseCounter::count(*document, getUseCounterType(policy->headerType()));
 
         if (allowDynamic())
-            UseCounter::count(*document, UseCounter::CSPWithUnsafeDynamic);
+            UseCounter::count(*document, UseCounter::CSPWithStrictDynamic);
     }
 
     // We disable 'eval()' even in the case of report-only policies, and rely on the check in the
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
index 00f82f5..507970f 100644
--- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -536,10 +536,15 @@
 
         distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSectionLogicalHeight));
 
-        for (LayoutTableSection* section = topSection(); section; section = sectionBelow(section))
+        LayoutTableSection* topSection = this->topSection();
+        LayoutUnit logicalOffset = topSection ? topSection->logicalTop() : LayoutUnit();
+        for (LayoutTableSection* section = topSection; section; section = sectionBelow(section)) {
+            section->setLogicalTop(logicalOffset);
             section->layoutRows();
+            logicalOffset += section->logicalHeight();
+        }
 
-        if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document().inQuirksMode()) {
+        if (!topSection && computedLogicalHeight > totalSectionLogicalHeight && !document().inQuirksMode()) {
             // Completely empty tables (with no sections or anything) should at least honor specified height
             // in strict mode.
             setLogicalHeight(logicalHeight() + computedLogicalHeight);
@@ -550,7 +555,7 @@
             sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
 
         // position the table sections
-        LayoutTableSection* section = topSection();
+        LayoutTableSection* section = topSection;
         while (section) {
             if (!sectionMoved && section->logicalTop() != logicalHeight())
                 sectionMoved = true;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
index 33440610..899b8c3 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
@@ -55,8 +55,9 @@
     calcViewport();
 
     // Allow LayoutSVGTransformableContainer to update its transform.
-    bool updatedTransform = calculateLocalTransform();
-    m_didScreenScaleFactorChange = updatedTransform || SVGLayoutSupport::screenScaleFactorChanged(parent());
+    TransformChange transformChange = calculateLocalTransform();
+    m_didScreenScaleFactorChange =
+        transformChange == TransformChange::Full || SVGLayoutSupport::screenScaleFactorChanged(parent());
 
     // LayoutSVGViewportContainer needs to set the 'layout size changed' flag.
     determineIfLayoutSizeChanged();
@@ -72,7 +73,7 @@
     if (everHadLayout() && needsLayout())
         SVGResourcesCache::clientLayoutChanged(this);
 
-    if (m_needsBoundariesUpdate || updatedTransform) {
+    if (m_needsBoundariesUpdate || transformChange != TransformChange::None) {
         updateCachedBoundaries();
         m_needsBoundariesUpdate = false;
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.h
index b3e1fee..8af1ed32 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.h
@@ -70,8 +70,17 @@
 
     bool nodeAtFloatPoint(HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
 
+    // The following enumeration is used to optimize cases where the scale is
+    // known to be invariant (see: LayoutSVGContainer::layout). The value
+    // 'Full' can be used in the general case when the scale change is unknown,
+    // or known to change.
+    enum class TransformChange {
+        None,
+        ScaleInvariant,
+        Full,
+    };
     // Allow LayoutSVGTransformableContainer to hook in at the right time in layout().
-    virtual bool calculateLocalTransform() { return false; }
+    virtual TransformChange calculateLocalTransform() { return TransformChange::None; }
 
     // Allow LayoutSVGViewportContainer to hook in at the right times in layout() and nodeAtFloatPoint().
     virtual void calcViewport() { }
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp
index 8653fca2..9f4b1c1 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.cpp
@@ -153,12 +153,12 @@
     m_viewport = FloatRect(0, 0, w, h);
 }
 
-bool LayoutSVGResourceMarker::calculateLocalTransform()
+LayoutSVGContainer::TransformChange LayoutSVGResourceMarker::calculateLocalTransform()
 {
     // TODO(fs): Temporarily, needing a layout implies that the local transform
     // has changed. This should be updated to be more precise and factor in the
     // actual (relevant) changes to the computed user-space transform.
-    return selfNeedsLayout();
+    return selfNeedsLayout() ? TransformChange::Full : TransformChange::None;
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h
index c81eaf7..7fd6a95 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceMarker.h
@@ -58,7 +58,7 @@
 private:
     void layout() override;
     void calcViewport() override;
-    bool calculateLocalTransform() override;
+    TransformChange calculateLocalTransform() override;
 
     AffineTransform viewportTransform() const;
 
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
index f33a86d9..8ba59de 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp
@@ -153,12 +153,11 @@
 
     SVGSVGElement* svg = toSVGSVGElement(node());
     ASSERT(svg);
-    m_isLayoutSizeChanged = selfNeedsLayout() || (svg->hasRelativeLengths() && oldSize != size());
     // When hasRelativeLengths() is false, no descendants have relative lengths
     // (hence no one is interested in viewport size changes).
-    bool layoutSizeChanged = m_isLayoutSizeChanged && svg->hasRelativeLengths();
+    m_isLayoutSizeChanged = svg->hasRelativeLengths() && (selfNeedsLayout() || oldSize != size());
 
-    SVGLayoutSupport::layoutChildren(firstChild(), false, m_didScreenScaleFactorChange, layoutSizeChanged);
+    SVGLayoutSupport::layoutChildren(firstChild(), false, m_didScreenScaleFactorChange, m_isLayoutSizeChanged);
 
     if (m_needsBoundariesOrTransformUpdate) {
         updateCachedBoundaries();
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.cpp
index e27c088..3c7b70ca 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.cpp
@@ -66,7 +66,18 @@
     return LayoutSVGContainer::isChildAllowed(child, style);
 }
 
-bool LayoutSVGTransformableContainer::calculateLocalTransform()
+void LayoutSVGTransformableContainer::setNeedsTransformUpdate()
+{
+    setMayNeedPaintInvalidationSubtree();
+    m_needsTransformUpdate = true;
+}
+
+static std::pair<double, double> scaleReference(const AffineTransform& transform)
+{
+    return std::make_pair(transform.xScaleSquared(), transform.yScaleSquared());
+}
+
+LayoutSVGContainer::TransformChange LayoutSVGTransformableContainer::calculateLocalTransform()
 {
     SVGGraphicsElement* element = toSVGGraphicsElement(this->element());
     ASSERT(element);
@@ -88,18 +99,23 @@
         FloatSize translation(
             useElement->x()->currentValue()->value(lengthContext),
             useElement->y()->currentValue()->value(lengthContext));
+        // TODO(fs): Signal this on style update instead. (Since these are
+        // suppose to be presentation attributes now, this does feel a bit
+        // broken...)
         if (translation != m_additionalTranslation)
-            m_needsTransformUpdate = true;
+            setNeedsTransformUpdate();
         m_additionalTranslation = translation;
     }
 
     if (!m_needsTransformUpdate)
-        return false;
+        return TransformChange::None;
 
+    std::pair<double, double> oldScale = scaleReference(m_localTransform);
     m_localTransform = element->calculateAnimatedLocalTransform();
     m_localTransform.translate(m_additionalTranslation.width(), m_additionalTranslation.height());
     m_needsTransformUpdate = false;
-    return true;
+    return scaleReference(m_localTransform) != oldScale
+        ? TransformChange::Full : TransformChange::ScaleInvariant;
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.h
index 2e3868e..b56fc83 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGTransformableContainer.h
@@ -37,10 +37,10 @@
     const AffineTransform& localToSVGParentTransform() const override { return m_localTransform; }
     const FloatSize& additionalTranslation() const { return m_additionalTranslation; }
 
-    void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+    void setNeedsTransformUpdate() override;
 
 private:
-    bool calculateLocalTransform() override;
+    TransformChange calculateLocalTransform() override;
     AffineTransform localSVGTransform() const override { return m_localTransform; }
 
     bool m_needsTransformUpdate : 1;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp
index d0d6937..b4ab298 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.cpp
@@ -64,14 +64,27 @@
     }
 }
 
-bool LayoutSVGViewportContainer::calculateLocalTransform()
+void LayoutSVGViewportContainer::setNeedsTransformUpdate()
+{
+    setMayNeedPaintInvalidationSubtree();
+    m_needsTransformUpdate = true;
+}
+
+static std::pair<double, double> scaleReference(const AffineTransform& transform)
+{
+    return std::make_pair(transform.xScaleSquared(), transform.yScaleSquared());
+}
+
+LayoutSVGContainer::TransformChange LayoutSVGViewportContainer::calculateLocalTransform()
 {
     if (!m_needsTransformUpdate)
-        return false;
+        return TransformChange::None;
 
+    std::pair<double, double> oldScale = scaleReference(m_localToParentTransform);
     m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
     m_needsTransformUpdate = false;
-    return true;
+    return scaleReference(m_localToParentTransform) != oldScale
+        ? TransformChange::Full : TransformChange::ScaleInvariant;
 }
 
 AffineTransform LayoutSVGViewportContainer::viewportTransform() const
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h
index 545e396..ac931d6 100644
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGViewportContainer.h
@@ -37,7 +37,7 @@
     bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
 
     void determineIfLayoutSizeChanged() override;
-    void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+    void setNeedsTransformUpdate() override;
 
     void paint(const PaintInfo&, const LayoutPoint&) const override;
 
@@ -50,7 +50,7 @@
     const AffineTransform& localToSVGParentTransform() const override { return m_localToParentTransform; }
 
     void calcViewport() override;
-    bool calculateLocalTransform() override;
+    TransformChange calculateLocalTransform() override;
 
     bool pointIsInsideViewportClip(const FloatPoint& pointInParent) override;
 
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
index f181b7a..6593acb 100644
--- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
+++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
@@ -510,7 +510,7 @@
     AffineTransform ctm = deprecatedCalculateTransformToLayer(layoutObject) * SubtreeContentTransformScope::currentContentTransformation();
     ctm.scale(layoutObject->document().frameHost()->deviceScaleFactorDeprecated());
 
-    return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
+    return narrowPrecisionToFloat(sqrt((ctm.xScaleSquared() + ctm.yScaleSquared()) / 2));
 }
 
 static inline bool compareCandidateDistance(const SearchCandidate& r1, const SearchCandidate& r2)
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
index 11174402..9d1e09b 100644
--- a/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/ResourceScriptMapping.js
@@ -320,10 +320,22 @@
             return false;
         if (typeof this._scriptSource === "undefined")
             return false;
-        if (!this._uiSourceCode.workingCopy().startsWith(this._scriptSource.trimRight()))
-            return true;
-        var suffix = this._uiSourceCode.workingCopy().substr(this._scriptSource.length);
-        return !!suffix.length && !suffix.match(WebInspector.Script.sourceURLRegex);
+        var workingCopy = this._uiSourceCode.workingCopy();
+
+        // Match ignoring sourceURL.
+        if (workingCopy.startsWith(this._scriptSource.trimRight())) {
+            var suffix = this._uiSourceCode.workingCopy().substr(this._scriptSource.length);
+            return !!suffix.length && !suffix.match(WebInspector.Script.sourceURLRegex);
+        }
+
+        // Match ignoring Node wrapper.
+        var nodePrefix = "(function (exports, require, module, __filename, __dirname) { \n";
+        var nodeSuffix = "\n});";
+        if (workingCopy.startsWith("#!/usr/bin/env node\n"))
+            workingCopy = workingCopy.substring("#!/usr/bin/env node\n".length);
+        if (this._scriptSource === nodePrefix + workingCopy + nodeSuffix)
+            return false;
+        return true;
     },
 
     /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/reportView.css b/third_party/WebKit/Source/devtools/front_end/ui/reportView.css
index 6ee0e9f..4ee8696b 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/reportView.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/reportView.css
@@ -78,7 +78,7 @@
 }
 
 .report-field-value {
-    flex: auto;
+    flex: none;
     padding: 0 6px;
     text-overflow: ellipsis;
     overflow: hidden;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/sidebarPane.css b/third_party/WebKit/Source/devtools/front_end/ui/sidebarPane.css
index 60dcbfc..476db58 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/sidebarPane.css
+++ b/third_party/WebKit/Source/devtools/front_end/ui/sidebarPane.css
@@ -81,6 +81,7 @@
     margin-right: 2px;
     content: "a";
     color: transparent;
+    flex-shrink: 0;
 }
 
 @media (-webkit-min-device-pixel-ratio: 1.5) {
diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h
index 9330378..24dd654e 100644
--- a/third_party/WebKit/Source/platform/heap/Heap.h
+++ b/third_party/WebKit/Source/platform/heap/Heap.h
@@ -336,13 +336,10 @@
 
     static inline size_t allocationSizeFromSize(size_t size)
     {
-        // Check the size before computing the actual allocation size.  The
-        // allocation size calculation can overflow for large sizes and the check
-        // therefore has to happen before any calculation on the size.
-        RELEASE_ASSERT(size < maxHeapObjectSize);
-
         // Add space for header.
         size_t allocationSize = size + sizeof(HeapObjectHeader);
+        // The allocation size calculation can overflow for large sizes.
+        RELEASE_ASSERT(allocationSize > size);
         // Align size with allocation granularity.
         allocationSize = (allocationSize + allocationMask) & ~allocationMask;
         return allocationSize;
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index 5f7d8fd1..94f89f28 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -2425,6 +2425,25 @@
     preciselyCollectGarbage();
 }
 
+TEST(HeapTest, LargeHashMap)
+{
+    clearOutOldGarbage();
+
+    size_t size = (1 << 27) / sizeof(int);
+    Persistent<HeapHashMap<int, Member<IntWrapper>>> map = new HeapHashMap<int, Member<IntWrapper>>();
+    map->reserveCapacityForSize(size);
+    EXPECT_LE(size, map->capacity());
+}
+
+TEST(HeapTest, LargeVector)
+{
+    clearOutOldGarbage();
+
+    size_t size = (1 << 27) / sizeof(int);
+    Persistent<HeapVector<int>> vector = new HeapVector<int>(size);
+    EXPECT_LE(size, vector->capacity());
+}
+
 typedef std::pair<Member<IntWrapper>, int> PairWrappedUnwrapped;
 typedef std::pair<int, Member<IntWrapper>> PairUnwrappedWrapped;
 typedef std::pair<WeakMember<IntWrapper>, Member<IntWrapper>> PairWeakStrong;
diff --git a/third_party/WebKit/Source/platform/heap/WrapperVisitor.h b/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
index d0b0bb8..a8348bd 100644
--- a/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
+++ b/third_party/WebKit/Source/platform/heap/WrapperVisitor.h
@@ -11,6 +11,7 @@
 namespace v8 {
 class Value;
 class Object;
+template <class T> class PersistentBase;
 }
 
 namespace blink {
@@ -32,6 +33,7 @@
     V(NodeMutationObserverData);                                     \
     V(NodeRareData);                                                 \
     V(StyleEngine);                                                  \
+    V(V8AbstractEventListener);                                      \
 
 #define FORWARD_DECLARE_SPECIAL_CLASSES(className)                   \
     class className;
@@ -97,8 +99,9 @@
         if (!traceable)
             return;
 
-        if (TraceTrait<T>::heapObjectHeader(traceable)->isWrapperHeaderMarked())
+        if (TraceTrait<T>::heapObjectHeader(traceable)->isWrapperHeaderMarked()) {
             return;
+        }
 
         pushToMarkingDeque(
             TraceTrait<T>::markWrapper,
@@ -112,7 +115,9 @@
         traceWrappers(t.get());
     }
 
-    virtual void traceWrappers(const ScopedPersistent<v8::Value>*) const = 0;
+    virtual void traceWrappers(const ScopedPersistent<v8::Value>* persistent) const = 0;
+    virtual void traceWrappers(const ScopedPersistent<v8::Object>* persistent) const = 0;
+    virtual void markWrapper(const v8::PersistentBase<v8::Object>* persistent) const = 0;
 
     virtual void dispatchTraceWrappers(const ScriptWrappable*) const = 0;
 #define DECLARE_DISPATCH_TRACE_WRAPPERS(className)                   \
diff --git a/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp b/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp
index 5bfbd0e..3f08a99d 100644
--- a/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp
+++ b/third_party/WebKit/Source/platform/transforms/AffineTransform.cpp
@@ -68,14 +68,24 @@
          && m_transform[4] == 0 && m_transform[5] == 0);
 }
 
+double AffineTransform::xScaleSquared() const
+{
+    return m_transform[0] * m_transform[0] + m_transform[1] * m_transform[1];
+}
+
 double AffineTransform::xScale() const
 {
-    return sqrt(m_transform[0] * m_transform[0] + m_transform[1] * m_transform[1]);
+    return sqrt(xScaleSquared());
+}
+
+double AffineTransform::yScaleSquared() const
+{
+    return m_transform[2] * m_transform[2] + m_transform[3] * m_transform[3];
 }
 
 double AffineTransform::yScale() const
 {
-    return sqrt(m_transform[2] * m_transform[2] + m_transform[3] * m_transform[3]);
+    return sqrt(yScaleSquared());
 }
 
 double AffineTransform::det() const
diff --git a/third_party/WebKit/Source/platform/transforms/AffineTransform.h b/third_party/WebKit/Source/platform/transforms/AffineTransform.h
index d369816f..8cf1bd26 100644
--- a/third_party/WebKit/Source/platform/transforms/AffineTransform.h
+++ b/third_party/WebKit/Source/platform/transforms/AffineTransform.h
@@ -110,7 +110,9 @@
     AffineTransform& skewX(double angle);
     AffineTransform& skewY(double angle);
 
+    double xScaleSquared() const;
     double xScale() const;
+    double yScaleSquared() const;
     double yScale() const;
 
     double det() const;
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index 4bd548b..faa4596 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@
 Short Name: crashpad
 URL: https://crashpad.chromium.org/
 Version: unknown
-Revision: 35da3b67357ee73d255ce49073f6765b77519e61
+Revision: 495a64fcdb7c979fe0f46eeaa1017087589d67cb
 License: Apache 2.0
 License File: crashpad/LICENSE
 Security Critical: yes
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
index 9b07e904..9837a9c 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
@@ -122,7 +122,7 @@
 
     if (section_segment_name != segment_name) {
       // cl_kernels modules (for OpenCL) aren’t ld output, and they’re formatted
-      // incorrectly on OS X 10.10 and 10.11. They have a single __TEXT segment,
+      // incorrectly on OS X 10.10 and later. They have a single __TEXT segment,
       // but one of the sections within it claims to belong to the __LD segment.
       // This mismatch shouldn’t happen. This errant section also has the
       // S_ATTR_DEBUG flag set, which shouldn’t happen unless all of the other
@@ -136,7 +136,7 @@
       bool ok = false;
       if (file_type == MH_BUNDLE && module_name == "cl_kernels") {
         int mac_os_x_minor_version = MacOSXMinorVersion();
-        if ((mac_os_x_minor_version == 10 || mac_os_x_minor_version == 11) &&
+        if ((mac_os_x_minor_version >= 10 && mac_os_x_minor_version <= 12) &&
             segment_name == SEG_TEXT &&
             section_segment_name == "__LD" &&
             section_name == "__compact_unwind" &&
@@ -173,27 +173,6 @@
       return false;
     }
 
-    uint32_t section_type = (section.flags & SECTION_TYPE);
-    bool zero_fill = section_type == S_ZEROFILL ||
-                     section_type == S_GB_ZEROFILL ||
-                     section_type == S_THREAD_LOCAL_ZEROFILL;
-
-    // Zero-fill section types aren’t mapped from the file, so their |offset|
-    // fields are irrelevant and are typically 0.
-    if (!zero_fill &&
-        section.offset - segment_command_.fileoff !=
-            section.addr - segment_command_.vmaddr) {
-      LOG(WARNING) << base::StringPrintf(
-                          "section type 0x%x at 0x%llx has unexpected offset "
-                          "0x%x in segment at 0x%llx with offset 0x%llx",
-                          section_type,
-                          section.addr,
-                          section.offset,
-                          segment_command_.vmaddr,
-                          segment_command_.fileoff) << section_info;
-      return false;
-    }
-
     const auto insert_result =
         section_map_.insert(std::make_pair(section_name, section_index));
     if (!insert_result.second) {
diff --git a/tools/isolate_driver.py b/tools/isolate_driver.py
index f75b4bdf7..ef25253 100755
--- a/tools/isolate_driver.py
+++ b/tools/isolate_driver.py
@@ -19,6 +19,7 @@
 'foo_test_run' analysed.
 """
 
+import errno
 import glob
 import json
 import logging
@@ -251,8 +252,13 @@
           for i in binary_deps),
     },
   }
-  if not os.path.isdir(temp_isolate_dir):
+  # Some .isolate files have the same temp directory and the build system may
+  # run this script in parallel so make directories safely here.
+  try:
     os.makedirs(temp_isolate_dir)
+  except OSError as e:
+    if e.errno != errno.EEXIST:
+      raise
   comment = (
       '# Warning: this file was AUTOGENERATED.\n'
       '# DO NO EDIT.\n')
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index fed867a..41c6cb8 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -113,7 +113,7 @@
       'CrWin7Goma(dbg)': 'gyp_debug_bot_minimal_symbols_x86',
       'CrWin7Goma(dll)': 'gyp_shared_release_bot_minimal_symbols_x86',
       'CrWinClang':
-        'swarming_gyp_clang_official_release_bot_minimal_symbols_x86',
+        'swarming_gn_clang_official_release_bot_minimal_symbols_x86',
       'CrWinClang(dbg)':
         'swarming_gyp_clang_debug_bot_minimal_symbols_x86',
       'CrWinClang(dbg) tester': 'none',
@@ -347,8 +347,8 @@
     },
 
     'chromium.mac': {
-      'Mac Builder': 'swarming_gpu_tests_gyp_release_bot',
-      'Mac Builder (dbg)': 'swarming_gyp_debug_bot',
+      'Mac Builder': 'swarming_gpu_tests_gn_release_bot',
+      'Mac Builder (dbg)': 'swarming_gn_debug_bot',
       'Mac GN (dbg)': 'gn_debug_bot',
       'Mac GN': 'gn_release_bot',
       'Mac10.10 Tests': 'none',
@@ -1680,6 +1680,10 @@
       'swarming', 'gpu_tests', 'gn', 'release_trybot', 'x86',
     ],
 
+    'swarming_gpu_tests_gn_release_bot': [
+      'swarming', 'gpu_tests', 'gn', 'release_bot',
+    ],
+
     'swarming_gpu_tests_gyp_release_bot': [
       'swarming', 'gpu_tests', 'gyp', 'release_bot',
     ],
@@ -1739,8 +1743,8 @@
       'minimal_symbols', 'x64',
     ],
 
-    'swarming_gyp_clang_official_release_bot_minimal_symbols_x86': [
-      'swarming', 'gyp', 'clang', 'official', 'release_bot',
+    'swarming_gn_clang_official_release_bot_minimal_symbols_x86': [
+      'swarming', 'gn', 'clang', 'official', 'release_bot',
       'minimal_symbols', 'x86',
     ],
 
@@ -1830,10 +1834,6 @@
       'release', 'x86',
     ],
 
-    'swarming_gyp_debug_bot': [
-      'swarming', 'gyp', 'debug_bot',
-    ],
-
     'swarming_gn_release_trybot_arm': [
       'swarming', 'gn', 'release_trybot', 'arm', 'crosscompile',
     ],
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index e69a850..16abf60b 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -65710,6 +65710,9 @@
   <int value="121" label="RFH_FAIL_PROVISIONAL_LOAD_NO_ERROR"/>
   <int value="122" label="NI_IN_PAGE_NAVIGATION"/>
   <int value="123" label="RPH_MOJO_PROCESS_ERROR"/>
+  <int value="124" label="DBMF_INVALID_ORIGIN_ON_GET_SPACE"/>
+  <int value="125" label="DBMF_INVALID_ORIGIN_ON_MODIFIED"/>
+  <int value="126" label="DBMF_INVALID_ORIGIN_ON_CLOSED"/>
 </enum>
 
 <enum name="BadMessageReasonExtensions" type="int">
@@ -75243,7 +75246,7 @@
   <int value="1274" label="ImageDocument"/>
   <int value="1275" label="ScriptPassesCSPDynamic"/>
   <int value="1276" label="ScriptPassesCSPNonce"/>
-  <int value="1277" label="CSPWithUnsafeDynamic"/>
+  <int value="1277" label="CSPWithStrictDynamic"/>
   <int value="1278" label="ScrollAnchored"/>
   <int value="1279" label="AddEventListenerFourArguments"/>
   <int value="1280" label="RemoveEventListenerFourArguments"/>
@@ -78736,6 +78739,7 @@
       label="Multiple aborted provisional loads at navigation start"/>
   <int value="7"
       label="User input received while not tracking a relevant committed load"/>
+  <int value="8" label="Inter process TimeTicks skew"/>
 </enum>
 
 <enum name="InterruptReason" type="int">
diff --git a/tools/perf/benchmarks/page_cycler_v2.py b/tools/perf/benchmarks/page_cycler_v2.py
index 3319c9d6..5b87c78 100644
--- a/tools/perf/benchmarks/page_cycler_v2.py
+++ b/tools/perf/benchmarks/page_cycler_v2.py
@@ -31,8 +31,8 @@
     tbm_options.SetTimelineBasedMetric('firstPaintMetric')
     return tbm_options
 
-
-@benchmark.Disabled('win', 'reference')  # crbug.com/615178, crbug.com/619254
+# crbug.com/615178, crbug.com/619254, crbug.com/621473
+@benchmark.Disabled('win', 'mac', 'linux', 'reference')
 class PageCyclerV2Typical25(_PageCyclerV2):
   """Page load time benchmark for a 25 typical web pages.
 
diff --git a/tools/perf/benchmarks/tracing.py b/tools/perf/benchmarks/tracing.py
index f62942f9..1e02e41 100644
--- a/tools/perf/benchmarks/tracing.py
+++ b/tools/perf/benchmarks/tracing.py
@@ -42,7 +42,7 @@
     options = timeline_based_measurement.Options(overhead_level=trace_memory)
     memory_dump_config = tracing_config.MemoryDumpConfig()
     memory_dump_config.AddTrigger('background', 200)
-    options.config.SetMemoryDumpConfig(memory_dump_config)
+    options.config.chrome_trace_config.SetMemoryDumpConfig(memory_dump_config)
     options.SetTimelineBasedMetric('tracingMetric')
     return options
 
diff --git a/tools/perf/page_sets/tough_canvas_cases/many_images/many_images.html b/tools/perf/page_sets/tough_canvas_cases/many_images/many_images.html
index f2a85397..72dc658 100644
--- a/tools/perf/page_sets/tough_canvas_cases/many_images/many_images.html
+++ b/tools/perf/page_sets/tough_canvas_cases/many_images/many_images.html
@@ -238,6 +238,7 @@
     <img src="images/image198_t.png" />
     <img src="images/image199_t.png" />
     <img src="images/image200_t.png" />
+<!-- Test was downsized to prevent crashes crbug.com/605553
     <img src="images/image201_t.png" />
     <img src="images/image202_t.png" />
     <img src="images/image203_t.png" />
@@ -438,6 +439,7 @@
     <img src="images/image398_t.png" />
     <img src="images/image399_t.png" />
     <img src="images/image400_t.png" />
+-->
   </div>
 </body>
 </html>
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn
index e9af237..d8ee478 100644
--- a/ui/base/ime/BUILD.gn
+++ b/ui/base/ime/BUILD.gn
@@ -137,6 +137,15 @@
     ]
   }
 
+  if (!is_chromeos && is_linux) {
+    sources += [
+      "linux/text_edit_command_auralinux.cc",
+      "linux/text_edit_command_auralinux.h",
+      "linux/text_edit_key_bindings_delegate_auralinux.cc",
+      "linux/text_edit_key_bindings_delegate_auralinux.h",
+    ]
+  }
+
   if (!toolkit_views && !use_aura) {
     sources -= [
       "input_method_factory.cc",
diff --git a/ui/events/linux/text_edit_command_auralinux.cc b/ui/base/ime/linux/text_edit_command_auralinux.cc
similarity index 91%
rename from ui/events/linux/text_edit_command_auralinux.cc
rename to ui/base/ime/linux/text_edit_command_auralinux.cc
index 4429225f..6a55076 100644
--- a/ui/events/linux/text_edit_command_auralinux.cc
+++ b/ui/base/ime/linux/text_edit_command_auralinux.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/events/linux/text_edit_command_auralinux.h"
+#include "ui/base/ime/linux/text_edit_command_auralinux.h"
 
 #include "base/logging.h"
 
@@ -23,10 +23,10 @@
     case DELETE_FORWARD:
       base_name = "DeleteForward";
       break;
-    case DELETE_TO_BEGINING_OF_LINE:
+    case DELETE_TO_BEGINNING_OF_LINE:
       base_name = "DeleteToBeginningOfLine";
       break;
-    case DELETE_TO_BEGINING_OF_PARAGRAPH:
+    case DELETE_TO_BEGINNING_OF_PARAGRAPH:
       base_name = "DeleteToBeginningOfParagraph";
       break;
     case DELETE_TO_END_OF_LINE:
@@ -65,13 +65,13 @@
     case MOVE_RIGHT:
       base_name = "MoveRight";
       break;
-    case MOVE_TO_BEGINING_OF_DOCUMENT:
+    case MOVE_TO_BEGINNING_OF_DOCUMENT:
       base_name = "MoveToBeginningOfDocument";
       break;
-    case MOVE_TO_BEGINING_OF_LINE:
+    case MOVE_TO_BEGINNING_OF_LINE:
       base_name = "MoveToBeginningOfLine";
       break;
-    case MOVE_TO_BEGINING_OF_PARAGRAPH:
+    case MOVE_TO_BEGINNING_OF_PARAGRAPH:
       base_name = "MoveToBeginningOfParagraph";
       break;
     case MOVE_TO_END_OF_DOCUMENT:
diff --git a/ui/events/linux/text_edit_command_auralinux.h b/ui/base/ime/linux/text_edit_command_auralinux.h
similarity index 75%
rename from ui/events/linux/text_edit_command_auralinux.h
rename to ui/base/ime/linux/text_edit_command_auralinux.h
index 82d3af2..12dd7a1 100644
--- a/ui/events/linux/text_edit_command_auralinux.h
+++ b/ui/base/ime/linux/text_edit_command_auralinux.h
@@ -2,26 +2,26 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UI_EVENTS_X_TEXT_EDIT_COMMAND_X11_H_
-#define UI_EVENTS_X_TEXT_EDIT_COMMAND_X11_H_
+#ifndef UI_BASE_IME_LINUX_TEXT_EDIT_COMMAND_AURALINUX_H_
+#define UI_BASE_IME_LINUX_TEXT_EDIT_COMMAND_AURALINUX_H_
 
 #include <string>
 
-#include "ui/events/events_export.h"
+#include "ui/base/ime/ui_base_ime_export.h"
 
 namespace ui {
 
 // Represents a command that performs a specific operation on text.
 // Copy and assignment are explicitly allowed; these objects live in vectors.
-class EVENTS_EXPORT TextEditCommandAuraLinux {
+class UI_BASE_IME_EXPORT TextEditCommandAuraLinux {
  public:
   enum CommandId {
     COPY,
     CUT,
     DELETE_BACKWARD,
     DELETE_FORWARD,
-    DELETE_TO_BEGINING_OF_LINE,
-    DELETE_TO_BEGINING_OF_PARAGRAPH,
+    DELETE_TO_BEGINNING_OF_LINE,
+    DELETE_TO_BEGINNING_OF_PARAGRAPH,
     DELETE_TO_END_OF_LINE,
     DELETE_TO_END_OF_PARAGRAPH,
     DELETE_WORD_BACKWARD,
@@ -34,9 +34,9 @@
     MOVE_PAGE_DOWN,
     MOVE_PAGE_UP,
     MOVE_RIGHT,
-    MOVE_TO_BEGINING_OF_DOCUMENT,
-    MOVE_TO_BEGINING_OF_LINE,
-    MOVE_TO_BEGINING_OF_PARAGRAPH,
+    MOVE_TO_BEGINNING_OF_DOCUMENT,
+    MOVE_TO_BEGINNING_OF_LINE,
+    MOVE_TO_BEGINNING_OF_PARAGRAPH,
     MOVE_TO_END_OF_DOCUMENT,
     MOVE_TO_END_OF_LINE,
     MOVE_TO_END_OF_PARAGRAPH,
@@ -53,8 +53,8 @@
   };
 
   TextEditCommandAuraLinux(CommandId command_id,
-                     const std::string& argument,
-                     bool extend_selection)
+                           const std::string& argument,
+                           bool extend_selection)
       : command_id_(command_id),
         argument_(argument),
         extend_selection_(extend_selection) {}
@@ -79,4 +79,4 @@
 
 }  // namespace ui
 
-#endif  // UI_EVENTS_X_TEXT_EDIT_COMMAND_X11_H_
+#endif  // UI_BASE_IME_LINUX_TEXT_EDIT_COMMAND_AURALINUX_H_
diff --git a/ui/events/linux/text_edit_key_bindings_delegate_auralinux.cc b/ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.cc
similarity index 80%
rename from ui/events/linux/text_edit_key_bindings_delegate_auralinux.cc
rename to ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.cc
index e6a941b..aaa8ca88 100644
--- a/ui/events/linux/text_edit_key_bindings_delegate_auralinux.cc
+++ b/ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 
 namespace ui {
 
@@ -12,7 +12,7 @@
 }
 
 void SetTextEditKeyBindingsDelegate(
-     TextEditKeyBindingsDelegateAuraLinux* delegate) {
+    TextEditKeyBindingsDelegateAuraLinux* delegate) {
   text_edit_keybinding_delegate_ = delegate;
 }
 
diff --git a/ui/events/linux/text_edit_key_bindings_delegate_auralinux.h b/ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h
similarity index 70%
rename from ui/events/linux/text_edit_key_bindings_delegate_auralinux.h
rename to ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h
index d291626..5ff03e3f 100644
--- a/ui/events/linux/text_edit_key_bindings_delegate_auralinux.h
+++ b/ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UI_EVENTS_X_TEXT_EDIT_KEY_BINDINGS_DELEGATE_X11_H_
-#define UI_EVENTS_X_TEXT_EDIT_KEY_BINDINGS_DELEGATE_X11_H_
+#ifndef UI_BASE_IME_LINUX_TEXT_EDIT_KEY_BINDINGS_DELEGATE_AURALINUX_H_
+#define UI_BASE_IME_LINUX_TEXT_EDIT_KEY_BINDINGS_DELEGATE_AURALINUX_H_
 
 #include <vector>
 
-#include "ui/events/events_export.h"
+#include "ui/base/ime/ui_base_ime_export.h"
 
 namespace ui {
 class Event;
@@ -18,7 +18,7 @@
 //
 // On desktop Linux, we've traditionally supported the user's custom
 // keybindings. We need to support this in both content/ and in views/.
-class EVENTS_EXPORT TextEditKeyBindingsDelegateAuraLinux {
+class UI_BASE_IME_EXPORT TextEditKeyBindingsDelegateAuraLinux {
  public:
   // Matches a key event against the users' platform specific key bindings,
   // false will be returned if the key event doesn't correspond to a predefined
@@ -33,11 +33,11 @@
 
 // Sets/Gets the global TextEditKeyBindingsDelegateAuraLinux. No ownership
 // changes. Can be NULL.
-EVENTS_EXPORT void SetTextEditKeyBindingsDelegate(
+UI_BASE_IME_EXPORT void SetTextEditKeyBindingsDelegate(
     TextEditKeyBindingsDelegateAuraLinux* delegate);
-EVENTS_EXPORT TextEditKeyBindingsDelegateAuraLinux*
-    GetTextEditKeyBindingsDelegate();
+UI_BASE_IME_EXPORT TextEditKeyBindingsDelegateAuraLinux*
+GetTextEditKeyBindingsDelegate();
 
 }  // namespace ui
 
-#endif  // UI_EVENTS_X_TEXT_EDIT_KEY_BINDINGS_DELEGATE_X11_H_
+#endif  // UI_BASE_IME_LINUX_TEXT_EDIT_KEY_BINDINGS_DELEGATE_AURALINUX_H_
diff --git a/ui/base/ime/ui_base_ime.gyp b/ui/base/ime/ui_base_ime.gyp
index 13a4185..8bc8d62 100644
--- a/ui/base/ime/ui_base_ime.gyp
+++ b/ui/base/ime/ui_base_ime.gyp
@@ -114,6 +114,10 @@
         'linux/linux_input_method_context.h',
         'linux/linux_input_method_context_factory.cc',
         'linux/linux_input_method_context_factory.h',
+        'linux/text_edit_command_auralinux.cc',
+        'linux/text_edit_command_auralinux.h',
+        'linux/text_edit_key_bindings_delegate_auralinux.cc',
+        'linux/text_edit_key_bindings_delegate_auralinux.h',
         'mock_input_method.cc',
         'mock_input_method.h',
         'text_edit_commands.h',
@@ -166,6 +170,12 @@
           'dependencies': [
             '../../../chromeos/chromeos.gyp:chromeos',
           ],
+          'sources!': [
+            'linux/text_edit_command_auralinux.cc',
+            'linux/text_edit_command_auralinux.h',
+            'linux/text_edit_key_bindings_delegate_auralinux.cc',
+            'linux/text_edit_key_bindings_delegate_auralinux.h',
+          ],
         }],
         ['use_aura==0 or (desktop_linux==0 and use_ozone==0)', {
           'sources!': [
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn
index e75df01..d499a0e 100644
--- a/ui/events/BUILD.gn
+++ b/ui/events/BUILD.gn
@@ -157,15 +157,6 @@
     ]
   }
 
-  if (!is_chromeos && is_linux) {
-    sources += [
-      "linux/text_edit_command_auralinux.cc",
-      "linux/text_edit_command_auralinux.h",
-      "linux/text_edit_key_bindings_delegate_auralinux.cc",
-      "linux/text_edit_key_bindings_delegate_auralinux.h",
-    ]
-  }
-
   if (use_ozone || (is_android && use_aura)) {
     sources += [ "events_default.cc" ]
   }
diff --git a/ui/events/devices/mojo/OWNERS b/ui/events/devices/mojo/OWNERS
index b9557c0..1841ff6 100644
--- a/ui/events/devices/mojo/OWNERS
+++ b/ui/events/devices/mojo/OWNERS
@@ -1,5 +1,5 @@
-per-file *struct_traits*.*=set noparent
-per-file *struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
 
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/events/events.gyp b/ui/events/events.gyp
index c164d0f..6d04fea 100644
--- a/ui/events/events.gyp
+++ b/ui/events/events.gyp
@@ -129,10 +129,6 @@
         'gestures/motion_event_aura.h',
         'keycodes/platform_key_map_win.cc',
         'keycodes/platform_key_map_win.h',
-        'linux/text_edit_command_auralinux.cc',
-        'linux/text_edit_command_auralinux.h',
-        'linux/text_edit_key_bindings_delegate_auralinux.cc',
-        'linux/text_edit_key_bindings_delegate_auralinux.h',
         'null_event_targeter.cc',
         'null_event_targeter.h',
         'scoped_target_handler.cc',
@@ -178,14 +174,6 @@
             'events_stub.cc',
           ],
         }],
-        ['chromeos==1', {
-          'sources!': [
-            'linux/text_edit_command_auralinux.cc',
-            'linux/text_edit_command_auralinux.h',
-            'linux/text_edit_key_bindings_delegate_auralinux.cc',
-            'linux/text_edit_key_bindings_delegate_auralinux.h',
-          ],
-        }],
         ['use_ozone==1', {
           'dependencies': [
             'ozone/events_ozone.gyp:events_ozone_layout',
diff --git a/ui/gfx/geometry/mojo/OWNERS b/ui/gfx/geometry/mojo/OWNERS
index b9557c0..1841ff6 100644
--- a/ui/gfx/geometry/mojo/OWNERS
+++ b/ui/gfx/geometry/mojo/OWNERS
@@ -1,5 +1,5 @@
-per-file *struct_traits*.*=set noparent
-per-file *struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
 
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/gfx/ipc/OWNERS b/ui/gfx/ipc/OWNERS
index aa5cab0..146c3c3c 100644
--- a/ui/gfx/ipc/OWNERS
+++ b/ui/gfx/ipc/OWNERS
@@ -1,2 +1,2 @@
-per-file *param_traits*.*=set noparent
-per-file *param_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/ui/gfx/ipc/geometry/OWNERS b/ui/gfx/ipc/geometry/OWNERS
index aa5cab0..146c3c3c 100644
--- a/ui/gfx/ipc/geometry/OWNERS
+++ b/ui/gfx/ipc/geometry/OWNERS
@@ -1,2 +1,2 @@
-per-file *param_traits*.*=set noparent
-per-file *param_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/ui/gfx/mojo/OWNERS b/ui/gfx/mojo/OWNERS
index b9557c0..1841ff6 100644
--- a/ui/gfx/mojo/OWNERS
+++ b/ui/gfx/mojo/OWNERS
@@ -1,5 +1,5 @@
-per-file *struct_traits*.*=set noparent
-per-file *struct_traits*.*=file://ipc/SECURITY_OWNERS
+per-file *_struct_traits*.*=set noparent
+per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
 
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/ui/ozone/platform/wayland/wayland_pointer.cc b/ui/ozone/platform/wayland/wayland_pointer.cc
index 7cdb4fbb..41edb3e 100644
--- a/ui/ozone/platform/wayland/wayland_pointer.cc
+++ b/ui/ozone/platform/wayland/wayland_pointer.cc
@@ -60,7 +60,8 @@
   pointer->location_.SetPoint(wl_fixed_to_double(surface_x),
                               wl_fixed_to_double(surface_y));
   MouseEvent event(ET_MOUSE_MOVED, gfx::Point(), gfx::Point(),
-                   base::TimeDelta::FromMilliseconds(time), pointer->flags_, 0);
+                   base::TimeTicks() + base::TimeDelta::FromMilliseconds(time),
+                   pointer->flags_, 0);
   event.set_location_f(pointer->location_);
   event.set_root_location_f(pointer->location_);
   pointer->callback_.Run(&event);
@@ -104,7 +105,8 @@
     pointer->flags_ &= ~flag;
   }
   MouseEvent event(type, gfx::Point(), gfx::Point(),
-                   base::TimeDelta::FromMilliseconds(time), flags, flag);
+                   base::TimeTicks() + base::TimeDelta::FromMilliseconds(time),
+                   flags, flag);
   event.set_location_f(pointer->location_);
   event.set_root_location_f(pointer->location_);
   pointer->callback_.Run(&event);
@@ -132,9 +134,10 @@
                  MouseWheelEvent::kWheelDelta);
   else
     return;
-  MouseWheelEvent event(offset, gfx::Point(), gfx::Point(),
-                        base::TimeDelta::FromMilliseconds(time),
-                        pointer->flags_, 0);
+  MouseWheelEvent event(
+      offset, gfx::Point(), gfx::Point(),
+      base::TimeTicks() + base::TimeDelta::FromMilliseconds(time),
+      pointer->flags_, 0);
   event.set_location_f(pointer->location_);
   event.set_root_location_f(pointer->location_);
   pointer->callback_.Run(&event);
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc
index 888780e..4890368 100644
--- a/ui/ozone/platform/wayland/wayland_window_unittest.cc
+++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/base_event_utils.h"
 #include "ui/events/event.h"
 #include "ui/ozone/platform/wayland/fake_server.h"
 #include "ui/ozone/platform/wayland/mock_platform_window_delegate.h"
@@ -29,7 +30,7 @@
       : test_mouse_event(ET_MOUSE_PRESSED,
                          gfx::Point(10, 15),
                          gfx::Point(10, 15),
-                         base::TimeDelta::FromSeconds(123456),
+                         ui::EventTimeStampFromSeconds(123456),
                          EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON,
                          EF_LEFT_MOUSE_BUTTON) {}
 
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index 374f8d8..24eb8bd 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -52,8 +52,8 @@
 
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
 #include "base/strings/utf_string_conversions.h"
-#include "ui/events/linux/text_edit_command_auralinux.h"
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_command_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #endif
 
 namespace views {
@@ -183,8 +183,8 @@
       return ui::TextEditCommand::DELETE_BACKWARD;
     case ui::TextEditCommandAuraLinux::DELETE_FORWARD:
       return ui::TextEditCommand::DELETE_FORWARD;
-    case ui::TextEditCommandAuraLinux::DELETE_TO_BEGINING_OF_LINE:
-    case ui::TextEditCommandAuraLinux::DELETE_TO_BEGINING_OF_PARAGRAPH:
+    case ui::TextEditCommandAuraLinux::DELETE_TO_BEGINNING_OF_LINE:
+    case ui::TextEditCommandAuraLinux::DELETE_TO_BEGINNING_OF_PARAGRAPH:
       return ui::TextEditCommand::DELETE_TO_BEGINNING_OF_LINE;
     case ui::TextEditCommandAuraLinux::DELETE_TO_END_OF_LINE:
     case ui::TextEditCommandAuraLinux::DELETE_TO_END_OF_PARAGRAPH:
@@ -220,9 +220,9 @@
     case ui::TextEditCommandAuraLinux::MOVE_RIGHT:
       return select ? ui::TextEditCommand::MOVE_RIGHT_AND_MODIFY_SELECTION
                     : ui::TextEditCommand::MOVE_RIGHT;
-    case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_DOCUMENT:
-    case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_LINE:
-    case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_PARAGRAPH:
+    case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_DOCUMENT:
+    case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_LINE:
+    case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINNING_OF_PARAGRAPH:
       return select ? ui::TextEditCommand::
                           MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
                     : ui::TextEditCommand::MOVE_TO_BEGINNING_OF_LINE;
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc
index 4707dcc26..b40de20 100644
--- a/ui/views/controls/textfield/textfield_unittest.cc
+++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -53,7 +53,7 @@
 #endif
 
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #endif
 
 #if defined(USE_X11)
diff --git a/ui/views/linux_ui/linux_ui.h b/ui/views/linux_ui/linux_ui.h
index 6eb3c26..86a3d5a 100644
--- a/ui/views/linux_ui/linux_ui.h
+++ b/ui/views/linux_ui/linux_ui.h
@@ -10,7 +10,7 @@
 #include "base/callback.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/base/ime/linux/linux_input_method_context_factory.h"
-#include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
+#include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
 #include "ui/gfx/linux_font_delegate.h"
 #include "ui/shell_dialogs/shell_dialog_linux.h"
 #include "ui/views/controls/button/button.h"
diff --git a/ui/webui/resources/cr_elements/compiled_resources2.gyp b/ui/webui/resources/cr_elements/compiled_resources2.gyp
index befb4d70..ac9ad685 100644
--- a/ui/webui/resources/cr_elements/compiled_resources2.gyp
+++ b/ui/webui/resources/cr_elements/compiled_resources2.gyp
@@ -7,9 +7,10 @@
       'target_name': 'cr_elements_resources',
       'type': 'none',
       'dependencies': [
+        'cr_profile_avatar_selector/compiled_resources2.gyp:*',
+        'cr_slider/compiled_resources2.gyp:*',
         'network/compiled_resources2.gyp:*',
         'policy/compiled_resources2.gyp:*',
-        'cr_slider/compiled_resources2.gyp:*',
       ],
     },
   ]
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/compiled_resources2.gyp
new file mode 100644
index 0000000..13303d9
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/compiled_resources2.gyp
@@ -0,0 +1,11 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+  'targets': [
+    {
+      'target_name': 'cr_profile_avatar_selector',
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    }
+  ],
+}
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
new file mode 100644
index 0000000..47cb8978
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
@@ -0,0 +1,62 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+
+<dom-module id="cr-profile-avatar-selector">
+  <template>
+    <style>
+      :host {
+        --avatar-spacing: 24px;
+        display: inline-flex;
+
+        @apply(--avatar-selector);
+      }
+
+      #selector {
+        display: flex;
+        flex-wrap: wrap;
+        margin: calc(var(--avatar-spacing) / -2);
+      }
+
+      .avatar {
+        --paper-button: {
+          background-color: var(--paper-grey-300);
+        };
+        --paper-button-flat-keyboard-focus: {
+          background-color: var(--paper-grey-400);
+        };
+        align-items: center;
+        border-radius: 2px;
+        border: 1px solid rgba(0, 0, 0, .12);
+        display: flex;
+        height: 48px;
+        justify-content: center;
+        margin: calc(var(--avatar-spacing) / 2);
+        min-width: 0;
+        padding: 0;
+        width: 48px;
+
+        @apply(--avatar-selector-avatar);
+      }
+
+      .avatar:hover {
+        @apply(--avatar-selector-avatar-hovered);
+      }
+
+      .avatar.iron-selected {
+        border: 1px solid var(--google-blue-500);
+
+        @apply(--avatar-selector-avatar-selected);
+      }
+    </style>
+    <iron-selector id="selector" selected="{{selectedAvatarUrl}}"
+        attr-for-selected="data-avatar-url">
+      <template is="dom-repeat" items="[[avatars]]">
+        <paper-button class="avatar" data-avatar-url$="[[item.url]]">
+          <img src="[[item.url]]" alt="[[item.label]]">
+        </paper-button>
+      </template>
+    </iron-selector>
+  </template>
+  <script src="cr_profile_avatar_selector.js"></script>
+</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js
new file mode 100644
index 0000000..cbb55e6
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js
@@ -0,0 +1,35 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview 'cr-profile-avatar-selector' is an element that displays
+ * profile avatar icons and allows an avatar to be selected.
+ */
+
+/** @typedef {{url: string, label: string}} */
+var AvatarIcon;
+
+Polymer({
+  is: 'cr-profile-avatar-selector',
+
+  properties: {
+    /**
+     * The currently selected profile avatar URL. May be a data URI.
+     * @type {string}
+     */
+    selectedAvatarUrl: {
+      type: String,
+      notify: true
+    },
+
+    /**
+     * The list of profile avatar URLs and labels.
+     * @type {!Array<!AvatarIcon>}
+     */
+    avatars: {
+      type: Array,
+      value: function() { return []; }
+    }
+  }
+});
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp
index e42aadf..a510004 100644
--- a/ui/webui/resources/cr_elements_resources.grdp
+++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -92,6 +92,12 @@
   <structure name="IDR_CR_ELEMENTS_CR_POLICY_PREF_INDICATOR_HTML"
              file="../../webui/resources/cr_elements/policy/cr_policy_pref_indicator.html"
              type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_PROFILE_AVATAR_SELECTOR_HTML"
+             file="../../webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html"
+             type="chrome_html" />
+  <structure name="IDR_CR_ELEMENTS_CR_PROFILE_AVATAR_SELECTOR_JS"
+             file="../../webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.js"
+             type="chrome_html" />
   <structure name="IDR_CR_ELEMENTS_CR_SEARCH_FIELD_BEHAVIOR_HTML"
              file="../../webui/resources/cr_elements/cr_search_field/cr_search_field_behavior.html"
              type="chrome_html" />
diff --git a/ui/wm/core/shadow_controller.cc b/ui/wm/core/shadow_controller.cc
index 76a2ae2c..f070b43 100644
--- a/ui/wm/core/shadow_controller.cc
+++ b/ui/wm/core/shadow_controller.cc
@@ -16,7 +16,6 @@
 #include "ui/aura/env_observer.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
-#include "ui/aura/window_property.h"
 #include "ui/base/ui_base_types.h"
 #include "ui/compositor/layer.h"
 #include "ui/wm/core/shadow.h"
@@ -26,9 +25,6 @@
 
 using std::make_pair;
 
-DECLARE_WINDOW_PROPERTY_TYPE(wm::Shadow*);
-DEFINE_OWNED_WINDOW_PROPERTY_KEY(wm::Shadow, kShadowLayerKey, nullptr);
-
 namespace wm {
 
 namespace {
@@ -110,6 +106,9 @@
  private:
   friend class base::RefCounted<Impl>;
   friend class ShadowController;
+  friend class ShadowController::TestApi;
+
+  typedef std::map<aura::Window*, linked_ptr<Shadow> > WindowShadowMap;
 
   Impl();
   ~Impl() override;
@@ -122,6 +121,10 @@
   // Checks if |window| is visible and contains a property requesting a shadow.
   bool ShouldShowShadowForWindow(aura::Window* window) const;
 
+  // Returns |window|'s shadow from |window_shadows_|, or NULL if no shadow
+  // exists.
+  Shadow* GetShadowForWindow(aura::Window* window);
+
   // Updates the shadow styles for windows when activation changes.
   void HandleWindowActivationChange(aura::Window* gaining_active,
                                     aura::Window* losing_active);
@@ -130,11 +133,12 @@
   // necessary).
   void HandlePossibleShadowVisibilityChange(aura::Window* window);
 
-  // Creates a new shadow for |window| and stores it with the |kShadowLayerKey|
-  // key.
-  // The shadow's bounds are initialized and it is added to the window's layer.
+  // Creates a new shadow for |window| and stores it in |window_shadows_|.  The
+  // shadow's bounds are initialized and it is added to the window's layer.
   void CreateShadowForWindow(aura::Window* window);
 
+  WindowShadowMap window_shadows_;
+
   ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
 
   static Impl* instance_;
@@ -161,18 +165,10 @@
 void ShadowController::Impl::OnWindowPropertyChanged(aura::Window* window,
                                                      const void* key,
                                                      intptr_t old) {
-  if (key == kShadowTypeKey) {
-    if (window->GetProperty(kShadowTypeKey) == static_cast<ShadowType>(old))
-      return;
-  } else if (key == aura::client::kShowStateKey) {
-    if (window->GetProperty(aura::client::kShowStateKey) ==
-        static_cast<ui::WindowShowState>(old)) {
-      return;
-    }
-  } else {
+  if (key == kShadowTypeKey || key == aura::client::kShowStateKey) {
+    HandlePossibleShadowVisibilityChange(window);
     return;
   }
-  HandlePossibleShadowVisibilityChange(window);
 }
 
 void ShadowController::Impl::OnWindowBoundsChanged(
@@ -185,7 +181,7 @@
 }
 
 void ShadowController::Impl::OnWindowDestroyed(aura::Window* window) {
-  window->ClearProperty(kShadowLayerKey);
+  window_shadows_.erase(window);
   observer_manager_.Remove(window);
 }
 
@@ -227,6 +223,11 @@
   }
 }
 
+Shadow* ShadowController::Impl::GetShadowForWindow(aura::Window* window) {
+  WindowShadowMap::const_iterator it = window_shadows_.find(window);
+  return it != window_shadows_.end() ? it->second.get() : NULL;
+}
+
 void ShadowController::Impl::HandlePossibleShadowVisibilityChange(
     aura::Window* window) {
   const bool should_show = ShouldShowShadowForWindow(window);
@@ -240,8 +241,8 @@
 }
 
 void ShadowController::Impl::CreateShadowForWindow(aura::Window* window) {
-  Shadow* shadow = new Shadow();
-  window->SetProperty(kShadowLayerKey, shadow);
+  linked_ptr<Shadow> shadow(new Shadow());
+  window_shadows_.insert(make_pair(window, shadow));
   shadow->Init(GetShadowStyleForWindow(window));
   shadow->SetContentBounds(gfx::Rect(window->bounds().size()));
   shadow->layer()->SetVisible(ShouldShowShadowForWindow(window));
@@ -261,10 +262,6 @@
 
 // ShadowController ------------------------------------------------------------
 
-Shadow* ShadowController::GetShadowForWindow(aura::Window* window) {
-  return window->GetProperty(kShadowLayerKey);
-}
-
 ShadowController::ShadowController(
     aura::client::ActivationClient* activation_client)
     : activation_client_(activation_client),
@@ -283,4 +280,10 @@
   impl_->OnWindowActivated(reason, gained_active, lost_active);
 }
 
+// ShadowController::TestApi ---------------------------------------------------
+
+Shadow* ShadowController::TestApi::GetShadowForWindow(aura::Window* window) {
+  return controller_->impl_->GetShadowForWindow(window);
+}
+
 }  // namespace wm
diff --git a/ui/wm/core/shadow_controller.h b/ui/wm/core/shadow_controller.h
index 3033c404..0d2be6b 100644
--- a/ui/wm/core/shadow_controller.h
+++ b/ui/wm/core/shadow_controller.h
@@ -34,8 +34,18 @@
 class WM_EXPORT ShadowController :
     public aura::client::ActivationChangeObserver {
  public:
-  // Returns the shadow for the |window|, or NULL if no shadow exists.
-  static Shadow* GetShadowForWindow(aura::Window* window);
+  class WM_EXPORT TestApi {
+   public:
+    explicit TestApi(ShadowController* controller) : controller_(controller) {}
+    ~TestApi() {}
+
+    Shadow* GetShadowForWindow(aura::Window* window);
+
+   private:
+    ShadowController* controller_;  // not owned
+
+    DISALLOW_COPY_AND_ASSIGN(TestApi);
+  };
 
   explicit ShadowController(aura::client::ActivationClient* activation_client);
   ~ShadowController() override;
diff --git a/ui/wm/core/shadow_controller_unittest.cc b/ui/wm/core/shadow_controller_unittest.cc
index e7fcd7f..61bc416 100644
--- a/ui/wm/core/shadow_controller_unittest.cc
+++ b/ui/wm/core/shadow_controller_unittest.cc
@@ -69,7 +69,8 @@
 
   // We should create the shadow before the window is visible (the shadow's
   // layer won't get drawn yet since it's a child of the window's layer).
-  const Shadow* shadow = ShadowController::GetShadowForWindow(window.get());
+  ShadowController::TestApi api(shadow_controller());
+  const Shadow* shadow = api.GetShadowForWindow(window.get());
   ASSERT_TRUE(shadow != NULL);
   EXPECT_TRUE(shadow->layer()->visible());
 
@@ -89,14 +90,10 @@
   // The shadow's layer should be a child of the window's layer.
   EXPECT_EQ(window->layer(), shadow->layer()->parent());
 
-  ui::Layer* layer_ptr =
-      ShadowController::GetShadowForWindow(window.get())->layer();
-  ui::Layer* parent_ptr = window->parent()->layer();
-  ASSERT_TRUE(parent_ptr->Contains(layer_ptr));
   window->parent()->RemoveChild(window.get());
+  aura::Window* window_ptr = window.get();
   window.reset();
-  // Layer should be gone now.
-  EXPECT_FALSE(parent_ptr->Contains(layer_ptr));
+  EXPECT_TRUE(api.GetShadowForWindow(window_ptr) == NULL);
 }
 
 // Tests that the window's shadow's bounds are updated correctly.
@@ -113,7 +110,8 @@
   // When the shadow is first created, it should use the window's size (but
   // remain at the origin, since it's a child of the window's layer).
   SetShadowType(window.get(), SHADOW_TYPE_RECTANGULAR);
-  const Shadow* shadow = ShadowController::GetShadowForWindow(window.get());
+  ShadowController::TestApi api(shadow_controller());
+  const Shadow* shadow = api.GetShadowForWindow(window.get());
   ASSERT_TRUE(shadow != NULL);
   EXPECT_EQ(gfx::Rect(kOldBounds.size()).ToString(),
             shadow->content_bounds().ToString());
@@ -127,6 +125,8 @@
 
 // Tests that activating a window changes the shadow style.
 TEST_F(ShadowControllerTest, ShadowStyle) {
+  ShadowController::TestApi api(shadow_controller());
+
   std::unique_ptr<aura::Window> window1(new aura::Window(NULL));
   window1->SetType(ui::wm::WINDOW_TYPE_NORMAL);
   window1->Init(ui::LAYER_TEXTURED);
@@ -136,7 +136,7 @@
   ActivateWindow(window1.get());
 
   // window1 is active, so style should have active appearance.
-  Shadow* shadow1 = ShadowController::GetShadowForWindow(window1.get());
+  Shadow* shadow1 = api.GetShadowForWindow(window1.get());
   ASSERT_TRUE(shadow1 != NULL);
   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());
 
@@ -150,7 +150,7 @@
   ActivateWindow(window2.get());
 
   // window1 is now inactive, so shadow should go inactive.
-  Shadow* shadow2 = ShadowController::GetShadowForWindow(window2.get());
+  Shadow* shadow2 = api.GetShadowForWindow(window2.get());
   ASSERT_TRUE(shadow2 != NULL);
   EXPECT_EQ(Shadow::STYLE_INACTIVE, shadow1->style());
   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow2->style());
@@ -158,13 +158,15 @@
 
 // Tests that shadow gets updated when the window show state changes.
 TEST_F(ShadowControllerTest, ShowState) {
+  ShadowController::TestApi api(shadow_controller());
+
   std::unique_ptr<aura::Window> window(new aura::Window(NULL));
   window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
   window->Init(ui::LAYER_TEXTURED);
   ParentWindow(window.get());
   window->Show();
 
-  Shadow* shadow = ShadowController::GetShadowForWindow(window.get());
+  Shadow* shadow = api.GetShadowForWindow(window.get());
   ASSERT_TRUE(shadow != NULL);
   EXPECT_EQ(Shadow::STYLE_INACTIVE, shadow->style());
 
@@ -180,6 +182,8 @@
 
 // Tests that we use smaller shadows for tooltips and menus.
 TEST_F(ShadowControllerTest, SmallShadowsForTooltipsAndMenus) {
+  ShadowController::TestApi api(shadow_controller());
+
   std::unique_ptr<aura::Window> tooltip_window(new aura::Window(NULL));
   tooltip_window->SetType(ui::wm::WINDOW_TYPE_TOOLTIP);
   tooltip_window->Init(ui::LAYER_TEXTURED);
@@ -187,8 +191,7 @@
   tooltip_window->SetBounds(gfx::Rect(10, 20, 300, 400));
   tooltip_window->Show();
 
-  Shadow* tooltip_shadow =
-      ShadowController::GetShadowForWindow(tooltip_window.get());
+  Shadow* tooltip_shadow = api.GetShadowForWindow(tooltip_window.get());
   ASSERT_TRUE(tooltip_shadow != NULL);
   EXPECT_EQ(Shadow::STYLE_SMALL, tooltip_shadow->style());
 
@@ -199,8 +202,7 @@
   menu_window->SetBounds(gfx::Rect(10, 20, 300, 400));
   menu_window->Show();
 
-  Shadow* menu_shadow =
-      ShadowController::GetShadowForWindow(tooltip_window.get());
+  Shadow* menu_shadow = api.GetShadowForWindow(tooltip_window.get());
   ASSERT_TRUE(menu_shadow != NULL);
   EXPECT_EQ(Shadow::STYLE_SMALL, menu_shadow->style());
 }
@@ -208,6 +210,8 @@
 // http://crbug.com/120210 - transient parents of certain types of transients
 // should not lose their shadow when they lose activation to the transient.
 TEST_F(ShadowControllerTest, TransientParentKeepsActiveShadow) {
+  ShadowController::TestApi api(shadow_controller());
+
   std::unique_ptr<aura::Window> window1(new aura::Window(NULL));
   window1->SetType(ui::wm::WINDOW_TYPE_NORMAL);
   window1->Init(ui::LAYER_TEXTURED);
@@ -217,7 +221,7 @@
   ActivateWindow(window1.get());
 
   // window1 is active, so style should have active appearance.
-  Shadow* shadow1 = ShadowController::GetShadowForWindow(window1.get());
+  Shadow* shadow1 = api.GetShadowForWindow(window1.get());
   ASSERT_TRUE(shadow1 != NULL);
   EXPECT_EQ(Shadow::STYLE_ACTIVE, shadow1->style());