diff --git a/AUTHORS b/AUTHORS
index cbdb0ae..a3d51be 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -349,6 +349,7 @@
 Jingyi Wei <wjywbs@gmail.com>
 Jinho Bang <jinho.bang@samsung.com>
 Jinkyu Seong <jinkyu.seong@lge.com>
+Jinsong Fan <fanjinsong@sogou-inc.com>
 Jinwoo Song <jinwoo7.song@samsung.com>
 Jitendra Kumar Sahoo <jitendra.ks@samsung.com>
 Joachim Bauch <mail@joachim-bauch.de>
diff --git a/BUILD.gn b/BUILD.gn
index 82a71f8a0..9378182 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -456,10 +456,7 @@
     }
 
     if (enable_extensions) {
-      deps += [
-        "//extensions/shell:app_shell",
-        "//extensions/shell/installer",
-      ]
+      deps += [ "//extensions/shell:app_shell" ]
     }
 
     if (enable_nacl) {
diff --git a/DEPS b/DEPS
index 1e7b884..43d68cd9 100644
--- a/DEPS
+++ b/DEPS
@@ -40,11 +40,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': '6a0feba05bd57e84103cebc695d4a217ec9e472e',
+  'skia_revision': '744d3c59be13f737e182e13a1fd2a12f87d230b2',
   # 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': 'fa1127207863b148988f8e6a4c9517379889aafe',
+  'v8_revision': '0e39219e0bc5b61f22f59820f9b4356a2403b399',
   # 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.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '53827cbbfebae66dd31f7aa30d3ee5c88716897a',
+  'pdfium_revision': '748793bd30ef25919c069f1856cc7e6ee0aee181',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
diff --git a/WATCHLISTS b/WATCHLISTS
index 769ae730..1ca13eb2e 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -1160,9 +1160,6 @@
                   '|ios/chrome/app/strings/ios(_.+)*_strings.grd'\
                   '|ui/strings/ui_strings.grd',
     },
-    'use_counter_features': {
-      'filepath': 'third_party/WebKit/public/platform/UseCounterFeature.def',
-    },
     'valgrind': {
       'filepath': 'valgrind',
     },
@@ -2278,7 +2275,6 @@
     'ui_display_win': ['robliao+watch@chromium.org'],
     'ui_resources': ['oshima+watch@chromium.org'],
     'ui_strings': ['srahim+watch@chromium.org'],
-    'use_counter_features': ['lunalu@chromium.org'],
     'valgrind': ['bruening+watch@chromium.org',
                  'glider+watch@chromium.org'],
     'version_assembly': ['caitkp+watch@chromium.org',
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc
index 23d3500..46e82a28 100644
--- a/android_webview/browser/aw_browser_terminator.cc
+++ b/android_webview/browser/aw_browser_terminator.cc
@@ -168,4 +168,4 @@
                  child_process_id, pid, base::Passed(std::move(pipe))));
 }
 
-}  // namespace breakpad
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_terminator.h b/android_webview/browser/aw_browser_terminator.h
index 074b171..9d58334 100644
--- a/android_webview/browser/aw_browser_terminator.h
+++ b/android_webview/browser/aw_browser_terminator.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 COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_BROWSER_TERMINATOR_H_
-#define COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_BROWSER_TERMINATOR_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_BROWSER_TERMINATOR_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_BROWSER_TERMINATOR_H_
 
 #include <map>
 
@@ -51,6 +51,6 @@
   DISALLOW_COPY_AND_ASSIGN(AwBrowserTerminator);
 };
 
-}  // namespace breakpad
+}  // namespace android_webview
 
-#endif  // COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_BROWSER_TERMINATOR_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_BROWSER_TERMINATOR_H_
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index c10225c..eb1ba34d 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.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 ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
-#define ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_CONTENT_BROWSER_CLIENT_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_CONTENT_BROWSER_CLIENT_H_
 
 #include <stddef.h>
 
@@ -142,4 +142,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_LIB_AW_CONTENT_BROWSER_CLIENT_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENT_BROWSER_CLIENT_H_
diff --git a/android_webview/browser/aw_contents_background_thread_client.h b/android_webview/browser/aw_contents_background_thread_client.h
index 73e3402..d7b5333d 100644
--- a/android_webview/browser/aw_contents_background_thread_client.h
+++ b/android_webview/browser/aw_contents_background_thread_client.h
@@ -21,6 +21,6 @@
       const base::android::JavaRef<jobjectArray>& requestHeaderNames,
       const base::android::JavaRef<jobjectArray>& requestHeaderValues);
 };
-}
+}  // namespace android_webview
 
 #endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_BACKGROUND_THREAD_CLIENT_H_
diff --git a/android_webview/browser/aw_contents_client_bridge_unittest.cc b/android_webview/browser/aw_contents_client_bridge_unittest.cc
index 923dee9..3baf051 100644
--- a/android_webview/browser/aw_contents_client_bridge_unittest.cc
+++ b/android_webview/browser/aw_contents_client_bridge_unittest.cc
@@ -158,4 +158,4 @@
   EXPECT_EQ(1, cert_selected_callbacks_);
 }
 
-}  // android_webview
+}  // namespace android_webview
diff --git a/android_webview/browser/aw_contents_lifecycle_notifier.h b/android_webview/browser/aw_contents_lifecycle_notifier.h
index fc2614f9..a2570d2 100644
--- a/android_webview/browser/aw_contents_lifecycle_notifier.h
+++ b/android_webview/browser/aw_contents_lifecycle_notifier.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 ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_LIFECYCLE_OBSERVER_H_
-#define ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_LIFECYCLE_OBSERVER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_LIFECYCLE_NOTIFIER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_LIFECYCLE_NOTIFIER_H_
 
 #include "base/android/jni_android.h"
 #include "base/macros.h"
@@ -21,4 +21,4 @@
 
 }  // namespace android_webview
 
-#endif
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_LIFECYCLE_NOTIFIER_H_
diff --git a/android_webview/browser/aw_contents_statics.h b/android_webview/browser/aw_contents_statics.h
index 26953df..03bd5e72 100644
--- a/android_webview/browser/aw_contents_statics.h
+++ b/android_webview/browser/aw_contents_statics.h
@@ -13,4 +13,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_STATICS_H_
diff --git a/android_webview/browser/aw_devtools_manager_delegate.h b/android_webview/browser/aw_devtools_manager_delegate.h
index 7251d3f..bf88194 100644
--- a/android_webview/browser/aw_devtools_manager_delegate.h
+++ b/android_webview/browser/aw_devtools_manager_delegate.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 ANDROID_WEBVIEW_NATIVE_AW_DEVTOOLS_MANAGER_DELEGATE_H_
-#define ANDROID_WEBVIEW_NATIVE_AW_DEVTOOLS_MANAGER_DELEGATE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_DEVTOOLS_MANAGER_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_DEVTOOLS_MANAGER_DELEGATE_H_
 
 #include <jni.h>
 
@@ -32,4 +32,4 @@
 
 } //  namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_AW_DEVTOOLS_MANAGER_DELEGATE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_DEVTOOLS_MANAGER_DELEGATE_H_
diff --git a/android_webview/browser/aw_picture.h b/android_webview/browser/aw_picture.h
index e6b39b1..28707559 100644
--- a/android_webview/browser/aw_picture.h
+++ b/android_webview/browser/aw_picture.h
@@ -42,4 +42,4 @@
 
 }  // android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_AW_PICTURE_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_PICTURE_H_
diff --git a/android_webview/browser/aw_printing_message_filter.h b/android_webview/browser/aw_printing_message_filter.h
index 0f62e85..a94e0c4 100644
--- a/android_webview/browser/aw_printing_message_filter.h
+++ b/android_webview/browser/aw_printing_message_filter.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 ANDROID_WEBVIEW_BROWSER_PRINTING_MESSAGE_FILTER_H_
-#define ANDROID_WEBVIEW_BROWSER_PRINTING_MESSAGE_FILTER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_PRINTING_MESSAGE_FILTER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_PRINTING_MESSAGE_FILTER_H_
 
 #include "base/macros.h"
 #include "content/public/browser/browser_message_filter.h"
@@ -42,4 +42,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_PRINTING_MESSAGE_FILTER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_PRINTING_MESSAGE_FILTER_H_
diff --git a/android_webview/browser/aw_renderer_priority_manager.h b/android_webview/browser/aw_renderer_priority_manager.h
index dec22415..6569d259 100644
--- a/android_webview/browser/aw_renderer_priority_manager.h
+++ b/android_webview/browser/aw_renderer_priority_manager.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 ANDROID_WEBVIEW_NATIVE_AW_RENDERER_PRIORITY_USER_DATA_H_
-#define ANDROID_WEBVIEW_NATIVE_AW_RENDERER_PRIORITY_USER_DATA_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_RENDERER_PRIORITY_MANAGER_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_RENDERER_PRIORITY_MANAGER_H_
 
 #include "base/supports_user_data.h"
 
@@ -39,4 +39,4 @@
 
 }  // namespace android_webview
 
-#endif  //  ANDROID_WEBVIEW_NATIVE_AW_RENDERER_PRIORITY_USER_DATA_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_AW_RENDERER_PRIORITY_MANAGER_H_
diff --git a/android_webview/browser/child_frame.cc b/android_webview/browser/child_frame.cc
index 6296351..f0d639b 100644
--- a/android_webview/browser/child_frame.cc
+++ b/android_webview/browser/child_frame.cc
@@ -47,4 +47,4 @@
   frame_future = nullptr;
 }
 
-}  // namespace webview
+}  // namespace android_webview
diff --git a/android_webview/browser/child_frame.h b/android_webview/browser/child_frame.h
index 2172eff..5e88f21 100644
--- a/android_webview/browser/child_frame.h
+++ b/android_webview/browser/child_frame.h
@@ -56,6 +56,6 @@
 
 using ChildFrameQueue = std::deque<std::unique_ptr<ChildFrame>>;
 
-}  // namespace webview
+}  // namespace android_webview
 
 #endif  // ANDROID_WEBVIEW_BROWSER_CHILD_FRAME_H_
diff --git a/android_webview/browser/compositor_frame_consumer.h b/android_webview/browser/compositor_frame_consumer.h
index cf7d1d6b..600ae42 100644
--- a/android_webview/browser/compositor_frame_consumer.h
+++ b/android_webview/browser/compositor_frame_consumer.h
@@ -60,4 +60,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_PRODUCER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_COMPOSITOR_FRAME_CONSUMER_H_
diff --git a/android_webview/browser/cookie_manager.cc b/android_webview/browser/cookie_manager.cc
index 0bf8fd8..cc09e6e 100644
--- a/android_webview/browser/cookie_manager.cc
+++ b/android_webview/browser/cookie_manager.cc
@@ -629,4 +629,4 @@
   return RegisterNativesImpl(env);
 }
 
-}  // android_webview namespace
+}  // namespace android_webview
diff --git a/android_webview/browser/net/aw_cookie_store_wrapper.h b/android_webview/browser/net/aw_cookie_store_wrapper.h
index eb90d7d5..cf8bfbd 100644
--- a/android_webview/browser/net/aw_cookie_store_wrapper.h
+++ b/android_webview/browser/net/aw_cookie_store_wrapper.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef ANDROID_WEBVIEW_BROWSER_NET_AW_COOKIE_STORE_WRAPPER_H_
+#define ANDROID_WEBVIEW_BROWSER_NET_AW_COOKIE_STORE_WRAPPER_H_
+
 #include <string>
 
 #include "base/bind.h"
@@ -127,4 +130,6 @@
   base::WeakPtrFactory<AwCookieStoreWrapper> weak_factory_;
 };
 
-}  // namesspace android_webview
+}  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_NET_AW_COOKIE_STORE_WRAPPER_H_
diff --git a/android_webview/browser/net/aw_network_change_notifier_factory.h b/android_webview/browser/net/aw_network_change_notifier_factory.h
index 6cfbd20..747cadb 100644
--- a/android_webview/browser/net/aw_network_change_notifier_factory.h
+++ b/android_webview/browser/net/aw_network_change_notifier_factory.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 ANDROID_WEBVIEW_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_
-#define ANDROID_WEBVIEW_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_
+#define ANDROID_WEBVIEW_BROWSER_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_
 
 #include "net/android/network_change_notifier_delegate_android.h"
 #include "net/base/network_change_notifier_factory.h"
@@ -38,4 +38,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_NET_AW_NETWORK_CHANGE_NOTIFIER_FACTORY_H_
diff --git a/android_webview/browser/net/input_stream_reader.h b/android_webview/browser/net/input_stream_reader.h
index 160fc03..56df3cd 100644
--- a/android_webview/browser/net/input_stream_reader.h
+++ b/android_webview/browser/net/input_stream_reader.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 ANDROID_WEBVIEW_NATIVE_INPUT_STREAM_READER_H_
-#define ANDROID_WEBVIEW_NATIVE_INPUT_STREAM_READER_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_NET_INPUT_STREAM_READER_H_
+#define ANDROID_WEBVIEW_BROWSER_NET_INPUT_STREAM_READER_H_
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -59,4 +59,4 @@
 
 } // namespace android_webview
 
-#endif //  ANDROID_WEBVIEW_NATIVE_INPUT_STREAM_READER_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_NET_INPUT_STREAM_READER_H_
diff --git a/android_webview/browser/parent_compositor_draw_constraints.cc b/android_webview/browser/parent_compositor_draw_constraints.cc
index 7a82218..dc05398 100644
--- a/android_webview/browser/parent_compositor_draw_constraints.cc
+++ b/android_webview/browser/parent_compositor_draw_constraints.cc
@@ -35,4 +35,4 @@
   return frame.viewport_rect_for_tile_priority_empty && !surface_rect_empty;
 }
 
-}  // namespace webview
+}  // namespace android_webview
diff --git a/android_webview/browser/permission/aw_permission_request.cc b/android_webview/browser/permission/aw_permission_request.cc
index 5426be72..8536d78d 100644
--- a/android_webview/browser/permission/aw_permission_request.cc
+++ b/android_webview/browser/permission/aw_permission_request.cc
@@ -92,4 +92,4 @@
   return RegisterNativesImpl(env);
 }
 
-}  // namespace android_webivew
+}  // namespace android_webview
diff --git a/android_webview/browser/permission/aw_permission_request.h b/android_webview/browser/permission/aw_permission_request.h
index ac516ea..cb2db75f 100644
--- a/android_webview/browser/permission/aw_permission_request.h
+++ b/android_webview/browser/permission/aw_permission_request.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 ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_H
-#define ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_H
+#ifndef ANDROID_WEBVIEW_BROWSER_PERMISSION_AW_PERMISSION_REQUEST_H_
+#define ANDROID_WEBVIEW_BROWSER_PERMISSION_AW_PERMISSION_REQUEST_H_
 
 #include <stdint.h>
 
@@ -82,6 +82,6 @@
 
 bool RegisterAwPermissionRequest(JNIEnv* env);
 
-}  // namespace android_webivew
+}  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_H
+#endif  // ANDROID_WEBVIEW_BROWSER_PERMISSION_AW_PERMISSION_REQUEST_H_
diff --git a/android_webview/browser/permission/aw_permission_request_delegate.cc b/android_webview/browser/permission/aw_permission_request_delegate.cc
index 2205501..8524204 100644
--- a/android_webview/browser/permission/aw_permission_request_delegate.cc
+++ b/android_webview/browser/permission/aw_permission_request_delegate.cc
@@ -10,4 +10,4 @@
 
 AwPermissionRequestDelegate::~AwPermissionRequestDelegate() {}
 
-}  // namespace android_webivew
+}  // namespace android_webview
diff --git a/android_webview/browser/permission/aw_permission_request_delegate.h b/android_webview/browser/permission/aw_permission_request_delegate.h
index 45d80c33..ea5c8d49 100644
--- a/android_webview/browser/permission/aw_permission_request_delegate.h
+++ b/android_webview/browser/permission/aw_permission_request_delegate.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 ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H
-#define ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H
+#ifndef ANDROID_WEBVIEW_BROWSER_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H_
 
 #include <stdint.h>
 
@@ -30,6 +30,6 @@
   DISALLOW_COPY_AND_ASSIGN(AwPermissionRequestDelegate);
 };
 
-}  // namespace android_webivew
+}  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H
+#endif  // ANDROID_WEBVIEW_BROWSER_PERMISSION_AW_PERMISSION_REQUEST_DELEGATE_H_
diff --git a/android_webview/browser/permission/media_access_permission_request.h b/android_webview/browser/permission/media_access_permission_request.h
index ed4429b..a6db85f 100644
--- a/android_webview/browser/permission/media_access_permission_request.h
+++ b/android_webview/browser/permission/media_access_permission_request.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 ANDROID_WEBVIEW_NATIVE_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H
-#define ANDROID_WEBVIEW_NATIVE_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H
+#ifndef ANDROID_WEBVIEW_BROWSER_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H_
+#define ANDROID_WEBVIEW_BROWSER_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H_
 
 #include <stdint.h>
 
@@ -42,4 +42,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H
+#endif  // ANDROID_WEBVIEW_BROWSER_PERMISSION_MEDIA_ACCESS_PERMISSION_REQUEST_H_
diff --git a/android_webview/browser/permission/permission_request_handler.cc b/android_webview/browser/permission/permission_request_handler.cc
index 2dc5cbb..287a7f7 100644
--- a/android_webview/browser/permission/permission_request_handler.cc
+++ b/android_webview/browser/permission/permission_request_handler.cc
@@ -139,4 +139,4 @@
          (resources & i->second) == resources;
 }
 
-}  // namespace android_webivew
+}  // namespace android_webview
diff --git a/android_webview/browser/permission/permission_request_handler.h b/android_webview/browser/permission/permission_request_handler.h
index 2b44394..c7037980 100644
--- a/android_webview/browser/permission/permission_request_handler.h
+++ b/android_webview/browser/permission/permission_request_handler.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 ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H
-#define ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H
+#ifndef ANDROID_WEBVIEW_BROWSER_PERMISSION_PERMISSION_REQUEST_HANDLER_H_
+#define ANDROID_WEBVIEW_BROWSER_PERMISSION_PERMISSION_REQUEST_HANDLER_H_
 
 #include <stdint.h>
 
@@ -79,6 +79,6 @@
   DISALLOW_COPY_AND_ASSIGN(PermissionRequestHandler);
 };
 
-}  // namespace android_webivew
+}  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H
+#endif  // ANDROID_WEBVIEW_BROWSER_PERMISSION_PERMISSION_REQUEST_HANDLER_H_
diff --git a/android_webview/browser/permission/permission_request_handler_client.cc b/android_webview/browser/permission/permission_request_handler_client.cc
index 17580c56..61a32ae 100644
--- a/android_webview/browser/permission/permission_request_handler_client.cc
+++ b/android_webview/browser/permission/permission_request_handler_client.cc
@@ -10,4 +10,4 @@
 
 PermissionRequestHandlerClient::~PermissionRequestHandlerClient() {}
 
-}  // namespace android_webiew
+}  // namespace android_webview
diff --git a/android_webview/browser/permission/permission_request_handler_client.h b/android_webview/browser/permission/permission_request_handler_client.h
index 586da3b0b..b09f7b8 100644
--- a/android_webview/browser/permission/permission_request_handler_client.h
+++ b/android_webview/browser/permission/permission_request_handler_client.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 ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H
-#define ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H
+#ifndef ANDROID_WEBVIEW_BROWSER_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H_
+#define ANDROID_WEBVIEW_BROWSER_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H_
 
 #include "base/android/scoped_java_ref.h"
 
@@ -22,6 +22,6 @@
   virtual void OnPermissionRequestCanceled(AwPermissionRequest* request) = 0;
 };
 
-}  // namespace android_webivew
+}  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H
+#endif  // ANDROID_WEBVIEW_BROWSER_PERMISSION_PERMISSION_REQUEST_HANDLER_CLIENT_H_
diff --git a/android_webview/browser/permission/permission_request_handler_unittest.cc b/android_webview/browser/permission/permission_request_handler_unittest.cc
index e0c9a83..9f87232 100644
--- a/android_webview/browser/permission/permission_request_handler_unittest.cc
+++ b/android_webview/browser/permission/permission_request_handler_unittest.cc
@@ -324,4 +324,4 @@
   EXPECT_EQ(NULL, client()->request());
 }
 
-}  // android_webview
+}  // namespace android_webview
diff --git a/android_webview/browser/permission/simple_permission_request.h b/android_webview/browser/permission/simple_permission_request.h
index fb8c637e..b720b20 100644
--- a/android_webview/browser/permission/simple_permission_request.h
+++ b/android_webview/browser/permission/simple_permission_request.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 ANDROID_WEBVIEW_NATIVE_PERMISSION_SIMPLE_PERMISSION_REQUEST_H
-#define ANDROID_WEBVIEW_NATIVE_PERMISSION_SIMPLE_PERMISSION_REQUEST_H
+#ifndef ANDROID_WEBVIEW_BROWSER_PERMISSION_SIMPLE_PERMISSION_REQUEST_H_
+#define ANDROID_WEBVIEW_BROWSER_PERMISSION_SIMPLE_PERMISSION_REQUEST_H_
 
 #include <stdint.h>
 
@@ -37,4 +37,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_NATIVE_PERMISSION_PROTECTED_MEDIA_ID_PERMISSION_REQUEST_H
+#endif  // ANDROID_WEBVIEW_BROWSER_PERMISSION_SIMPLE_PERMISSION_REQUEST_H_
diff --git a/android_webview/browser/popup_touch_handle_drawable.cc b/android_webview/browser/popup_touch_handle_drawable.cc
index 3bd0bc6..f230a1e 100644
--- a/android_webview/browser/popup_touch_handle_drawable.cc
+++ b/android_webview/browser/popup_touch_handle_drawable.cc
@@ -94,4 +94,4 @@
       new PopupTouchHandleDrawable(env, obj, horizontal_padding_ratio));
 }
 
-}  // namespace content
+}  // namespace android_webview
diff --git a/android_webview/browser/popup_touch_handle_drawable.h b/android_webview/browser/popup_touch_handle_drawable.h
index 7d678d4d..4feece0 100644
--- a/android_webview/browser/popup_touch_handle_drawable.h
+++ b/android_webview/browser/popup_touch_handle_drawable.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 CONTENT_BROWSER_ANDROID_POPUP_TOUCH_HANDLE_DRAWABLE_H_
-#define CONTENT_BROWSER_ANDROID_POPUP_TOUCH_HANDLE_DRAWABLE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_POPUP_TOUCH_HANDLE_DRAWABLE_H_
+#define ANDROID_WEBVIEW_BROWSER_POPUP_TOUCH_HANDLE_DRAWABLE_H_
 
 #include "ui/touch_selection/touch_handle.h"
 
@@ -43,6 +43,6 @@
   DISALLOW_COPY_AND_ASSIGN(PopupTouchHandleDrawable);
 };
 
-}  // namespace content
+}  // namespace android_webview
 
-#endif  // CONTENT_BROWSER_ANDROID_POPUP_TOUCH_HANDLE_DRAWABLE_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_POPUP_TOUCH_HANDLE_DRAWABLE_H_
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.h b/android_webview/browser/renderer_host/aw_render_view_host_ext.h
index c0dcbde..1a81257 100644
--- a/android_webview/browser/renderer_host/aw_render_view_host_ext.h
+++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.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 ANDROID_WEBVIEW_BROWSER_RENDER_HOST_RENDER_VIEW_HOST_EXT_H_
-#define ANDROID_WEBVIEW_BROWSER_RENDER_HOST_RENDER_VIEW_HOST_EXT_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_RENDERER_HOST_AW_RENDER_VIEW_HOST_EXT_H_
+#define ANDROID_WEBVIEW_BROWSER_RENDERER_HOST_AW_RENDER_VIEW_HOST_EXT_H_
 
 #include "content/public/browser/web_contents_observer.h"
 
@@ -123,4 +123,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_BROWSER_RENDER_HOST_RENDER_VIEW_HOST_EXT_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_RENDERER_HOST_AW_RENDER_VIEW_HOST_EXT_H_
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
index 4ff41775..271ce914 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.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 ANDROID_WEBVIEW_LIB_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
-#define ANDROID_WEBVIEW_LIB_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
+#ifndef ANDROID_WEBVIEW_BROWSER_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
+#define ANDROID_WEBVIEW_BROWSER_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
 
 #include <map>
 #include <memory>
@@ -94,4 +94,4 @@
 
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_LIB_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_H_
+#endif  // ANDROID_WEBVIEW_BROWSER_RENDERER_HOST_AW_RESOURCE_DISPATCHER_HOST_DELEGATE_H_
diff --git a/android_webview/browser/scoped_app_gl_state_restore.h b/android_webview/browser/scoped_app_gl_state_restore.h
index b15d14bc..48ec461 100644
--- a/android_webview/browser/scoped_app_gl_state_restore.h
+++ b/android_webview/browser/scoped_app_gl_state_restore.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef ANDROID_WEBVIEW_BROWSER_SCOPED_APP_GL_STATE_RESTORE_H_
+#define ANDROID_WEBVIEW_BROWSER_SCOPED_APP_GL_STATE_RESTORE_H_
+
 #include <memory>
 #include <vector>
 
@@ -55,3 +58,5 @@
 };
 
 }  // namespace android_webview
+
+#endif  // ANDROID_WEBVIEW_BROWSER_SCOPED_APP_GL_STATE_RESTORE_H_
diff --git a/android_webview/browser/state_serializer.h b/android_webview/browser/state_serializer.h
index 15346c1..6745135 100644
--- a/android_webview/browser/state_serializer.h
+++ b/android_webview/browser/state_serializer.h
@@ -63,7 +63,7 @@
                                       content::NavigationEntry* entry)
     WARN_UNUSED_RESULT;
 
-}  // namespace interanl
+}  // namespace internal
 
 }  // namespace android_webview
 
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc
index a04bf5f5..7520a12 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/surfaces_instance.cc
@@ -73,13 +73,17 @@
           DeferredGpuCommandService::GetInstance())));
   output_surface_ = output_surface_holder.get();
   std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
-      nullptr, output_surface_holder->capabilities().max_frames_pending));
+      begin_frame_source_.get(), nullptr,
+      output_surface_holder->capabilities().max_frames_pending));
   display_.reset(new cc::Display(
       nullptr /* shared_bitmap_manager */,
       nullptr /* gpu_memory_buffer_manager */, settings, frame_sink_id_,
-      begin_frame_source_.get(), std::move(output_surface_holder),
-      std::move(scheduler), std::move(texture_mailbox_deleter)));
+      std::move(output_surface_holder), std::move(scheduler),
+      std::move(texture_mailbox_deleter)));
   display_->Initialize(this, surface_manager_.get());
+  surface_manager_->RegisterBeginFrameSource(begin_frame_source_.get(),
+                                             frame_sink_id_);
+
   display_->SetVisible(true);
 
   DCHECK(!g_surfaces_instance);
@@ -88,6 +92,7 @@
 
 SurfacesInstance::~SurfacesInstance() {
   DCHECK_EQ(g_surfaces_instance, this);
+  surface_manager_->UnregisterBeginFrameSource(begin_frame_source_.get());
   g_surfaces_instance = nullptr;
   DCHECK(child_ids_.empty());
 }
diff --git a/android_webview/browser/test/rendering_test.cc b/android_webview/browser/test/rendering_test.cc
index d20aa18..5a65e3e 100644
--- a/android_webview/browser/test/rendering_test.cc
+++ b/android_webview/browser/test/rendering_test.cc
@@ -45,7 +45,7 @@
  private:
   RenderingTest* const rendering_test_;
 };
-}
+}  // namespace
 
 RenderingTest::RenderingTest() : message_loop_(new base::MessageLoop) {
   // TODO(boliu): Update unit tests to async code path.
diff --git a/android_webview/browser/token_binding_manager_bridge.cc b/android_webview/browser/token_binding_manager_bridge.cc
index 1aaa0ec..5a4213de 100644
--- a/android_webview/browser/token_binding_manager_bridge.cc
+++ b/android_webview/browser/token_binding_manager_bridge.cc
@@ -116,4 +116,4 @@
   return RegisterNativesImpl(env);
 }
 
-}  // android_webview namespace
+}  // namespace android_webview
diff --git a/android_webview/common/crash_reporter/aw_microdump_crash_reporter.h b/android_webview/common/crash_reporter/aw_microdump_crash_reporter.h
index 1f719af..500009c 100644
--- a/android_webview/common/crash_reporter/aw_microdump_crash_reporter.h
+++ b/android_webview/common/crash_reporter/aw_microdump_crash_reporter.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 ANDROID_WEBVIEW_CRASH_REPORTER_AW_MICRODUMP_CRASH_REPORTER_H_
-#define ANDROID_WEBVIEW_CRASH_REPORTER_AW_MICRODUMP_CRASH_REPORTER_H_
+#ifndef ANDROID_WEBVIEW_COMMON_CRASH_REPORTER_AW_MICRODUMP_CRASH_REPORTER_H_
+#define ANDROID_WEBVIEW_COMMON_CRASH_REPORTER_AW_MICRODUMP_CRASH_REPORTER_H_
 
 #include <string>
 
@@ -24,4 +24,4 @@
 }  // namespace crash_reporter
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_CRASH_REPORTER_AW_MICRODUMP_CRASH_REPORTER_H_
+#endif  // ANDROID_WEBVIEW_COMMON_CRASH_REPORTER_AW_MICRODUMP_CRASH_REPORTER_H_
diff --git a/android_webview/common/crash_reporter/crash_keys.h b/android_webview/common/crash_reporter/crash_keys.h
index aedfdfc..d9be49c 100644
--- a/android_webview/common/crash_reporter/crash_keys.h
+++ b/android_webview/common/crash_reporter/crash_keys.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 ANDROID_WEBVIEW_COMMON_CRASH_KEYS_H_
-#define ANDROID_WEBVIEW_COMMON_CRASH_KEYS_H_
+#ifndef ANDROID_WEBVIEW_COMMON_CRASH_REPORTER_CRASH_KEYS_H_
+#define ANDROID_WEBVIEW_COMMON_CRASH_REPORTER_CRASH_KEYS_H_
 
 #include <stddef.h>
 #include <string>
@@ -37,4 +37,4 @@
 }  // namespace crash_keys
 }  // namespace android_webview
 
-#endif  // ANDROID_WEBVIEW_COMMON_CRASH_KEYS_H_
+#endif  // ANDROID_WEBVIEW_COMMON_CRASH_REPORTER_CRASH_KEYS_H_
diff --git a/android_webview/lib/webview_jni_onload.cc b/android_webview/lib/webview_jni_onload.cc
index 5418258..a91a462c 100644
--- a/android_webview/lib/webview_jni_onload.cc
+++ b/android_webview/lib/webview_jni_onload.cc
@@ -55,4 +55,4 @@
   return true;
 }
 
-}  // android_webview
+}  // namespace android_webview
diff --git a/android_webview/renderer/aw_content_settings_client.cc b/android_webview/renderer/aw_content_settings_client.cc
index 6d2a981..293ca2d 100644
--- a/android_webview/renderer/aw_content_settings_client.cc
+++ b/android_webview/renderer/aw_content_settings_client.cc
@@ -22,7 +22,7 @@
   return !gurl.IsStandard();
 }
 
-}
+}  // namespace
 
 AwContentSettingsClient::AwContentSettingsClient(
     content::RenderFrame* render_frame)
diff --git a/android_webview/renderer/aw_render_frame_ext.h b/android_webview/renderer/aw_render_frame_ext.h
index 672946b4..9fd50194 100644
--- a/android_webview/renderer/aw_render_frame_ext.h
+++ b/android_webview/renderer/aw_render_frame_ext.h
@@ -60,7 +60,7 @@
   DISALLOW_COPY_AND_ASSIGN(AwRenderFrameExt);
 };
 
-}
+}  // namespace android_webview
 
 #endif  // ANDROID_WEBVIEW_RENDERER_AW_RENDER_FRAME_EXT_H_
 
diff --git a/android_webview/renderer/aw_render_thread_observer.cc b/android_webview/renderer/aw_render_thread_observer.cc
index 01ac1da4..c147604 100644
--- a/android_webview/renderer/aw_render_thread_observer.cc
+++ b/android_webview/renderer/aw_render_thread_observer.cc
@@ -42,4 +42,4 @@
   blink::WebNetworkStateNotifier::SetOnLine(network_up);
 }
 
-}  // nanemspace android_webview
+}  // namespace android_webview
diff --git a/android_webview/test/unittest/assets/asset_file.ogg b/android_webview/test/unittest/assets/asset_file.ogg
index 1e9e1a1..ab0f967 100644
--- a/android_webview/test/unittest/assets/asset_file.ogg
+++ b/android_webview/test/unittest/assets/asset_file.ogg
@@ -3,5 +3,5 @@
 
 This is a text file, but we use the .ogg extension so that aapt will not
 compress its contents. This is ok for the purpose of the unit tests since
-they do not play the media, and they are only interested in the existance of
+they do not play the media, and they are only interested in the existence of
 an uncompressed media file in the assets directory.
diff --git a/ash/app_list/app_list_delegate_impl.cc b/ash/app_list/app_list_delegate_impl.cc
index ef2f8c9..1ff3bfc3 100644
--- a/ash/app_list/app_list_delegate_impl.cc
+++ b/ash/app_list/app_list_delegate_impl.cc
@@ -5,15 +5,13 @@
 #include "ash/app_list/app_list_delegate_impl.h"
 
 #include "ash/root_window_controller.h"
-#include "ash/shelf/app_list_button.h"
-#include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_widget.h"
 #include "ash/shell.h"
 #include "ash/shell_port.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/app_list/presenter/app_list.h"
 
 namespace ash {
-
+// TODO(newcomer): Remove this class as a part of crbug.com/726838
 AppListDelegateImpl::AppListDelegateImpl() {
   Shell::Get()->app_list()->set_delegate(this);
 }
@@ -24,17 +22,11 @@
 
 void AppListDelegateImpl::OnAppListVisibilityChanged(bool visible,
                                                      int64_t display_id) {
-  aura::Window* root_window =
-      ShellPort::Get()->GetRootWindowForDisplayId(display_id);
-  AppListButton* app_list_button =
-      Shelf::ForWindow(root_window)->shelf_widget()->GetAppListButton();
-  if (!app_list_button)
-    return;
-
-  if (visible)
-    app_list_button->OnAppListShown();
-  else
-    app_list_button->OnAppListDismissed();
+  if (app_list::features::IsFullscreenAppListEnabled()) {
+    aura::Window* root_window =
+        ShellPort::Get()->GetRootWindowForDisplayId(display_id);
+    Shell::Get()->OnAppListVisibilityChanged(visible, root_window);
+  }
 }
 
 }  // namespace ash
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc
index 01b2bcc5..fc81a0ab 100644
--- a/ash/app_list/app_list_presenter_delegate.cc
+++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -119,13 +119,9 @@
 
 void AppListPresenterDelegate::OnShown(int64_t display_id) {
   is_visible_ = true;
-  // Update applist button status when app list visibility is changed.
   aura::Window* root_window =
       ShellPort::Get()->GetRootWindowForDisplayId(display_id);
-  AppListButton* app_list_button =
-      Shelf::ForWindow(root_window)->shelf_widget()->GetAppListButton();
-  if (app_list_button)
-    app_list_button->OnAppListShown();
+  Shell::Get()->OnAppListVisibilityChanged(is_visible_, root_window);
 }
 
 void AppListPresenterDelegate::OnDismissed() {
@@ -133,12 +129,9 @@
   DCHECK(view_);
 
   is_visible_ = false;
-
-  // Update applist button status when app list visibility is changed.
-  Shelf* shelf = Shelf::ForWindow(view_->GetWidget()->GetNativeWindow());
-  AppListButton* app_list_button = shelf->shelf_widget()->GetAppListButton();
-  if (app_list_button)
-    app_list_button->OnAppListDismissed();
+  aura::Window* root_window =
+      RootWindowController::ForTargetRootWindow()->GetRootWindow();
+  Shell::Get()->OnAppListVisibilityChanged(is_visible_, root_window);
 }
 
 void AppListPresenterDelegate::UpdateBounds() {
diff --git a/ash/app_list/app_list_presenter_delegate_unittest.cc b/ash/app_list/app_list_presenter_delegate_unittest.cc
index ab85c94..3d27aa20 100644
--- a/ash/app_list/app_list_presenter_delegate_unittest.cc
+++ b/ash/app_list/app_list_presenter_delegate_unittest.cc
@@ -5,6 +5,7 @@
 #include <memory>
 
 #include "ash/ash_switches.h"
+#include "ash/public/cpp/config.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
@@ -14,6 +15,8 @@
 #include "base/macros.h"
 #include "base/test/scoped_feature_list.h"
 #include "ui/app_list/app_list_features.h"
+#include "ui/app_list/app_list_switches.h"
+#include "ui/app_list/views/app_list_main_view.h"
 #include "ui/app_list/views/app_list_view.h"
 #include "ui/aura/test/test_windows.h"
 #include "ui/aura/window.h"
@@ -54,12 +57,12 @@
     UpdateDisplay("1024x768");
   }
 
- private:
   void EnableFullscreenAppList() {
     scoped_feature_list_.InitAndEnableFeature(
         app_list::features::kEnableFullscreenAppList);
   }
 
+ private:
   test::TestAppListViewPresenterImpl app_list_presenter_impl_;
   bool test_with_fullscreen_;
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -71,7 +74,7 @@
 // the parameterized tests.
 INSTANTIATE_TEST_CASE_P(, AppListPresenterDelegateTest, testing::Bool());
 
-// Tests that app launcher hides when focus moves to a normal window.
+// Tests that app list hides when focus moves to a normal window.
 TEST_P(AppListPresenterDelegateTest, HideOnFocusOut) {
   app_list_presenter_impl()->Show(GetPrimaryDisplayId());
   EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility());
@@ -82,7 +85,7 @@
   EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility());
 }
 
-// Tests that app launcher remains visible when focus is moved to a different
+// Tests that app list remains visible when focus is moved to a different
 // window in kShellWindowId_AppListContainer.
 TEST_P(AppListPresenterDelegateTest,
        RemainVisibleWhenFocusingToApplistContainer) {
@@ -140,7 +143,7 @@
   EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility());
 }
 
-// Tests opening the app launcher on a non-primary display, then deleting the
+// Tests opening the app list on a non-primary display, then deleting the
 // display.
 TEST_P(AppListPresenterDelegateTest, NonPrimaryDisplay) {
   // Set up a screen with two displays (horizontally adjacent).
@@ -163,7 +166,7 @@
   EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility());
 }
 
-// Tests opening the app launcher on a tiny display that is too small to contain
+// Tests opening the app list on a tiny display that is too small to contain
 // it.
 TEST_F(AppListPresenterDelegateTest, TinyDisplay) {
   // Set up a screen with a tiny display (height smaller than the app list).
@@ -186,4 +189,67 @@
   EXPECT_GE(app_list_view_top, kMinimalAppListMargin);
 }
 
+// Tests that the peeking app list is enlarged to fullscreen after the user
+// types in the search box.
+TEST_F(AppListPresenterDelegateTest, SnapToFullscreenAfterSearchboxInput) {
+  // TODO(newcomer): investigate failure in mash. http://crbug.com/726838.
+  if (Shell::GetAshConfig() == Config::MASH)
+    return;
+
+  EnableFullscreenAppList();
+  UpdateDisplay("1024x768");
+  EXPECT_TRUE(app_list::features::IsFullscreenAppListEnabled());
+  app_list_presenter_impl()->Show(GetPrimaryDisplayId());
+  app_list::AppListView* app_list = app_list_presenter_impl()->GetView();
+  // Check that it is in peeking mode.
+  EXPECT_FALSE(app_list->is_fullscreen());
+
+  // Dummy key event to search box.
+  ui::test::EventGenerator& generator = GetEventGenerator();
+  generator.PressKey(ui::KeyboardCode::VKEY_0, 0);
+  // Check that it is in fullscreen mode.
+  EXPECT_TRUE(app_list->is_fullscreen());
+}
+
+// Tests that the peeking app list closes if the user taps outside its
+// bounds.
+TEST_F(AppListPresenterDelegateTest, TapAndClickOutsideClosesPeekingAppList) {
+  EnableFullscreenAppList();
+
+  app_list_presenter_impl()->Show(GetPrimaryDisplayId());
+  EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility());
+  ui::test::EventGenerator& generator = GetEventGenerator();
+
+  // Grab the bounds of the search box,
+  // which is guaranteed to be inside the app list.
+  gfx::Point tap_point = app_list_presenter_impl()
+                             ->GetView()
+                             ->search_box_widget()
+                             ->GetContentsView()
+                             ->GetBoundsInScreen()
+                             .CenterPoint();
+
+  // Tapping inside the bounds doesn't close the app list.
+  generator.GestureTapAt(tap_point);
+  EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility());
+
+  // Clicking inside the bounds doesn't close the app list.
+  generator.MoveMouseTo(tap_point);
+  generator.ClickLeftButton();
+  EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility());
+
+  // Tapping outside the bounds closes the app list.
+  tap_point.set_x(tap_point.x() + 750);
+  generator.GestureTapAt(tap_point);
+  EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility());
+
+  app_list_presenter_impl()->Show(GetPrimaryDisplayId());
+  EXPECT_TRUE(app_list_presenter_impl()->GetTargetVisibility());
+
+  // Clicking outside the bounds closes the app list.
+  generator.MoveMouseTo(tap_point);
+  generator.ClickLeftButton();
+  EXPECT_FALSE(app_list_presenter_impl()->GetTargetVisibility());
+}
+
 }  // namespace ash
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h
index d5ae3c0..7d0b3f1 100644
--- a/ash/public/cpp/shell_window_ids.h
+++ b/ash/public/cpp/shell_window_ids.h
@@ -56,6 +56,9 @@
   // The container for top-level windows with the 'always-on-top' flag set.
   kShellWindowId_AlwaysOnTopContainer,
 
+  // The container for the app list.
+  kShellWindowId_AppListContainer,
+
   // The container for the shelf.
   kShellWindowId_ShelfContainer,
 
@@ -65,9 +68,6 @@
   // The container for panel windows.
   kShellWindowId_PanelContainer,
 
-  // The container for the app list.
-  kShellWindowId_AppListContainer,
-
   // The container for user-specific modal windows.
   kShellWindowId_SystemModalContainer,
 
@@ -137,10 +137,10 @@
     kShellWindowId_VirtualKeyboardContainer,
     kShellWindowId_DefaultContainer,
     kShellWindowId_AlwaysOnTopContainer,
+    kShellWindowId_AppListContainer,
     kShellWindowId_ShelfContainer,
     kShellWindowId_ShelfBubbleContainer,
     kShellWindowId_PanelContainer,
-    kShellWindowId_AppListContainer,
     kShellWindowId_SystemModalContainer,
     kShellWindowId_LockScreenWallpaperContainer,
     kShellWindowId_LockScreenContainer,
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 7910744..14c0548 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -897,6 +897,12 @@
   wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container);
   always_on_top_container->SetProperty(kUsesScreenCoordinatesKey, true);
 
+  aura::Window* app_list_container =
+      CreateContainer(kShellWindowId_AppListContainer, "AppListContainer",
+                      non_lock_screen_containers);
+  wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
+  app_list_container->SetProperty(kUsesScreenCoordinatesKey, true);
+
   aura::Window* shelf_container =
       CreateContainer(kShellWindowId_ShelfContainer, "ShelfContainer",
                       non_lock_screen_containers);
@@ -917,12 +923,6 @@
   shelf_bubble_container->SetProperty(kUsesScreenCoordinatesKey, true);
   shelf_bubble_container->SetProperty(kLockedToRootKey, true);
 
-  aura::Window* app_list_container =
-      CreateContainer(kShellWindowId_AppListContainer, "AppListContainer",
-                      non_lock_screen_containers);
-  wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
-  app_list_container->SetProperty(kUsesScreenCoordinatesKey, true);
-
   aura::Window* modal_container =
       CreateContainer(kShellWindowId_SystemModalContainer,
                       "SystemModalContainer", non_lock_screen_containers);
diff --git a/ash/shelf/app_list_button.cc b/ash/shelf/app_list_button.cc
index 584d9d8..efecc29 100644
--- a/ash/shelf/app_list_button.cc
+++ b/ash/shelf/app_list_button.cc
@@ -44,7 +44,7 @@
   DCHECK(listener_);
   DCHECK(shelf_view_);
   DCHECK(shelf_);
-
+  Shell::Get()->AddShellObserver(this);
   SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER);
   set_ink_drop_base_color(kShelfInkDropBaseColor);
   set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity);
@@ -55,7 +55,9 @@
   set_notify_action(CustomButton::NOTIFY_ON_PRESS);
 }
 
-AppListButton::~AppListButton() {}
+AppListButton::~AppListButton() {
+  Shell::Get()->RemoveShellObserver(this);
+}
 
 void AppListButton::OnAppListShown() {
   AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr);
@@ -239,4 +241,15 @@
   }
 }
 
+void AppListButton::OnAppListVisibilityChanged(bool shown,
+                                               aura::Window* root_window) {
+  if (shelf_ != Shelf::ForWindow(root_window))
+    return;
+
+  if (shown)
+    OnAppListShown();
+  else
+    OnAppListDismissed();
+}
+
 }  // namespace ash
diff --git a/ash/shelf/app_list_button.h b/ash/shelf/app_list_button.h
index 02c69c2..fa9a35b 100644
--- a/ash/shelf/app_list_button.h
+++ b/ash/shelf/app_list_button.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "ash/ash_export.h"
+#include "ash/shell_observer.h"
 #include "base/macros.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/views/controls/button/image_button.h"
@@ -18,7 +19,8 @@
 class ShelfView;
 
 // Button used for the AppList icon on the shelf.
-class ASH_EXPORT AppListButton : public views::ImageButton {
+class ASH_EXPORT AppListButton : public views::ImageButton,
+                                 public ShellObserver {
  public:
   AppListButton(InkDropButtonListener* listener,
                 ShelfView* shelf_view,
@@ -55,6 +57,10 @@
   // ink drops.
   gfx::Point GetCenterPoint() const;
 
+  // ShellObserver overrides:
+  void OnAppListVisibilityChanged(bool shown,
+                                  aura::Window* root_window) override;
+
   // True if the app list is currently showing for this display.
   // This is useful because other IsApplistVisible functions aren't per-display.
   bool is_showing_app_list_;
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc
index 3b2c1704..d5474587 100644
--- a/ash/shelf/shelf_layout_manager.cc
+++ b/ash/shelf/shelf_layout_manager.cc
@@ -28,6 +28,7 @@
 #include "base/auto_reset.h"
 #include "base/command_line.h"
 #include "base/i18n/rtl.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
@@ -425,6 +426,16 @@
       &keyboard_observer_);
 }
 
+void ShelfLayoutManager::OnAppListVisibilityChanged(bool shown,
+                                                    aura::Window* root_window) {
+  if (shelf_ != Shelf::ForWindow(root_window))
+    return;
+
+  is_app_list_visible_ = shown;
+  if (app_list::features::IsFullscreenAppListEnabled())
+    MaybeUpdateShelfBackground(AnimationChangeType::IMMEDIATE);
+}
+
 void ShelfLayoutManager::OnWindowActivated(ActivationReason reason,
                                            aura::Window* gained_active,
                                            aura::Window* lost_active) {
@@ -468,6 +479,10 @@
   if (state_.session_state != session_manager::SessionState::ACTIVE)
     return SHELF_BACKGROUND_OVERLAP;
 
+  // If the app list is active, hide the shelf background to prevent overlap.
+  if (is_app_list_visible_ && app_list::features::IsFullscreenAppListEnabled())
+    return SHELF_BACKGROUND_DEFAULT;
+
   if (state_.visibility_state != SHELF_AUTO_HIDE &&
       state_.window_state == wm::WORKSPACE_WINDOW_STATE_MAXIMIZED) {
     return SHELF_BACKGROUND_MAXIMIZED;
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h
index 7e66fb2..7c3731a 100644
--- a/ash/shelf/shelf_layout_manager.h
+++ b/ash/shelf/shelf_layout_manager.h
@@ -64,7 +64,6 @@
 
   // Clears internal data for shutdown process.
   void PrepareForShutdown();
-
   // Returns whether the shelf and its contents (shelf, status) are visible
   // on the screen.
   bool IsVisible() const;
@@ -138,6 +137,8 @@
   void OnPinnedStateChanged(aura::Window* pinned_window) override;
   void OnVirtualKeyboardStateChanged(bool activated,
                                      aura::Window* root_window) override;
+  void OnAppListVisibilityChanged(bool shown,
+                                  aura::Window* root_window) override;
 
   // Overridden from wm::ActivationChangeObserver:
   void OnWindowActivated(ActivationReason reason,
@@ -317,6 +318,10 @@
   // Do any windows overlap the shelf? This is maintained by WorkspaceManager.
   bool window_overlaps_shelf_;
 
+  // Is the AppList visible? This is maintained by
+  // OnAppListVisibilityChanged.
+  bool is_app_list_visible_ = false;
+
   base::OneShotTimer auto_hide_timer_;
 
   // Whether the mouse was over the shelf when the auto hide timer started.
diff --git a/ash/shell.cc b/ash/shell.cc
index 6ef34b2b..1186c21 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -553,6 +553,12 @@
   g_is_browser_process_with_mash = true;
 }
 
+void Shell::OnAppListVisibilityChanged(bool visible,
+                                       aura::Window* root_window) {
+  for (auto& observer : shell_observers_)
+    observer.OnAppListVisibilityChanged(visible, root_window);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Shell, private:
 
@@ -916,11 +922,9 @@
   if (!display_initialized)
     display_manager_->InitDefaultDisplay();
 
-  // TODO(sky): move this to chrome for mash. http://crbug.com/729824.
-  if (ShouldEnableSimplifiedDisplayManagement())
+  if (config == Config::CLASSIC) {
     display_manager_->RefreshFontParams();
 
-  if (config == Config::CLASSIC) {
     aura::Env::GetInstance()->set_context_factory(init_params.context_factory);
     aura::Env::GetInstance()->set_context_factory_private(
         init_params.context_factory_private);
diff --git a/ash/shell.h b/ash/shell.h
index 45a6995..6be67bc5 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -18,6 +18,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "ui/app_list/presenter/app_list_delegate.h"
 #include "ui/aura/window.h"
 #include "ui/display/screen.h"
 #include "ui/events/event_target.h"
@@ -609,6 +610,8 @@
   // Used to provide better error messages for Shell::Get() under mash.
   static void SetIsBrowserProcessWithMash();
 
+  void OnAppListVisibilityChanged(bool visible, aura::Window* root_window);
+
  private:
   FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, TestCursor);
   FRIEND_TEST_ALL_PREFIXES(WindowManagerTest, MouseEventCursors);
diff --git a/ash/shell_observer.h b/ash/shell_observer.h
index 563f2a59..fc0bbaf8 100644
--- a/ash/shell_observer.h
+++ b/ash/shell_observer.h
@@ -16,6 +16,10 @@
 
 class ASH_EXPORT ShellObserver {
  public:
+  // Called when the AppList is shown or dismissed.
+  virtual void OnAppListVisibilityChanged(bool shown,
+                                          aura::Window* root_window) {}
+
   // Called when a casting session is started or stopped.
   virtual void OnCastingSessionStartedOrStopped(bool started) {}
 
diff --git a/ash/system/audio/volume_view.cc b/ash/system/audio/volume_view.cc
index 9d42635..1a7fad8 100644
--- a/ash/system/audio/volume_view.cc
+++ b/ash/system/audio/volume_view.cc
@@ -174,9 +174,6 @@
   if (is_default_view_ && !audio_handler->has_alternative_output() &&
       !audio_handler->has_alternative_input()) {
     tri_view_->SetContainerVisible(TriView::Container::END, false);
-    // TODO(tdanderson): TriView itself should trigger a relayout when the
-    // visibility of one of its containers is changed.
-    tri_view_->InvalidateLayout();
     return;
   }
 
diff --git a/ash/system/palette/palette_tool_manager.h b/ash/system/palette/palette_tool_manager.h
index e21addde..001a3409 100644
--- a/ash/system/palette/palette_tool_manager.h
+++ b/ash/system/palette/palette_tool_manager.h
@@ -82,8 +82,8 @@
   // Returns the active tool for the given group.
   PaletteToolId GetActiveTool(PaletteGroup group);
 
-  // Fetch the active tray icon for the given tool. Returns
-  // gfx::VectorIconId::VECTOR_ICON_NONE if not available.
+  // Fetch the active tray icon for the given tool. Returns an empty icon if
+  // not available.
   const gfx::VectorIcon& GetActiveTrayIcon(PaletteToolId tool_id) const;
 
   // Create views for all of the registered tools.
diff --git a/ash/system/tray/tri_view.cc b/ash/system/tray/tri_view.cc
index d9d54c4..6bc3211 100644
--- a/ash/system/tray/tri_view.cc
+++ b/ash/system/tray/tri_view.cc
@@ -124,7 +124,10 @@
 }
 
 void TriView::SetContainerVisible(Container container, bool visible) {
+  if (GetContainer(container)->visible() == visible)
+    return;
   GetContainer(container)->SetVisible(visible);
+  Layout();
 }
 
 void TriView::SetFlexForContainer(Container container, int flex) {
diff --git a/ash/system/tray/tri_view.h b/ash/system/tray/tri_view.h
index 86359aa..ab145a3 100644
--- a/ash/system/tray/tri_view.h
+++ b/ash/system/tray/tri_view.h
@@ -101,6 +101,7 @@
   // Sets whether the |container| is visible. During a layout the space will be
   // allocated to the visible containers only. i.e. non-visible containers will
   // not be allocated any space.
+  // Note: This will cause a relayout.
   void SetContainerVisible(Container container, bool visible);
 
   // Sets the flex weight for the given |container|. Using the preferred size as
diff --git a/ash/system/tray/tri_view_unittest.cc b/ash/system/tray/tri_view_unittest.cc
index c949063..52dcc4e3 100644
--- a/ash/system/tray/tri_view_unittest.cc
+++ b/ash/system/tray/tri_view_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <utility>
 
 #include "ash/system/tray/tri_view.h"
 #include "base/memory/ptr_util.h"
@@ -377,4 +378,34 @@
   EXPECT_EQ(kMinHeight, GetMinHeight(TriView::Container::END));
 }
 
+TEST_F(TriViewTest, ChangingContainersVisibilityPerformsLayout) {
+  const int kViewWidth = 10;
+  const int kViewHeight = 10;
+  const gfx::Size kEndViewSize(kViewWidth, kViewHeight);
+
+  tri_view_->SetBounds(0, 0, 3 * kViewWidth, kViewHeight);
+  tri_view_->SetFlexForContainer(TriView::Container::CENTER, 1.f);
+
+  views::View* start_child = new views::View();
+  start_child->SetPreferredSize(kEndViewSize);
+
+  views::View* center_child = new views::View();
+  center_child->SetPreferredSize(gfx::Size(2 * kViewWidth, kViewHeight));
+
+  views::View* end_child = new views::View();
+  end_child->SetPreferredSize(kEndViewSize);
+
+  tri_view_->AddView(TriView::Container::START, start_child);
+  tri_view_->AddView(TriView::Container::CENTER, center_child);
+  tri_view_->AddView(TriView::Container::END, end_child);
+
+  tri_view_->Layout();
+
+  EXPECT_EQ(gfx::Size(kViewWidth, kViewHeight), center_child->size());
+
+  tri_view_->SetContainerVisible(TriView::Container::END, false);
+
+  EXPECT_EQ(gfx::Size(2 * kViewWidth, kViewHeight), center_child->size());
+}
+
 }  // namespace ash
diff --git a/ash/wm/maximize_mode/maximize_mode_controller.cc b/ash/wm/maximize_mode/maximize_mode_controller.cc
index 39b21cd..99202c1 100644
--- a/ash/wm/maximize_mode/maximize_mode_controller.cc
+++ b/ash/wm/maximize_mode/maximize_mode_controller.cc
@@ -118,7 +118,7 @@
 
   // TODO(jonross): Do not create MaximizeModeController if the flag is
   // unavailable. This will require refactoring
-  // IsMaximizeModeWindowManagerEnabled to check for the existance of the
+  // IsMaximizeModeWindowManagerEnabled to check for the existence of the
   // controller.
   if (IsEnabled()) {
     ShellPort::Get()->AddDisplayObserver(this);
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
index 219ab712..5306c3e 100644
--- a/base/metrics/sample_vector.cc
+++ b/base/metrics/sample_vector.cc
@@ -272,7 +272,7 @@
       // Point |counts_| to the newly created storage. This is done while
       // locked to prevent possible concurrent calls to CreateCountsStorage
       // but, between that call and here, other threads could notice the
-      // existance of the storage and race with this to set_counts(). That's
+      // existence of the storage and race with this to set_counts(). That's
       // okay because (a) it's atomic and (b) it always writes the same value.
       set_counts(counts);
     }
diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py
index 0e0e51e..748775a 100755
--- a/build/android/resource_sizes.py
+++ b/build/android/resource_sizes.py
@@ -593,7 +593,7 @@
 
 
 def _PrintStaticInitializersCountFromApk(apk_filename, tools_prefix,
-                                         chartjson=None):
+                                         dump_sis, chartjson=None):
   with zipfile.ZipFile(apk_filename) as z:
     so_files = [f for f in z.infolist()
                 if f.filename.endswith('.so') and f.file_size > 0]
@@ -610,7 +610,8 @@
     unstripped_path = os.path.join(out_dir, 'lib.unstripped', lib_name)
     if os.path.exists(unstripped_path):
       si_count += _PrintStaticInitializersCount(
-          apk_filename, so_info.filename, unstripped_path, tools_prefix)
+          apk_filename, so_info.filename, unstripped_path, tools_prefix,
+          dump_sis)
     else:
       raise Exception('Unstripped .so not found. Looked here: %s',
                       unstripped_path)
@@ -619,16 +620,16 @@
 
 
 def _PrintStaticInitializersCount(apk_path, apk_so_name, so_with_symbols_path,
-                                  tools_prefix):
+                                  tools_prefix, dump_sis):
   """Counts the number of static initializers in the given shared library.
-     Additionally, files for which static initializers were found are printed
-     on the standard output.
 
      Args:
       apk_path: Path to the apk.
       apk_so_name: Name of the so.
       so_with_symbols_path: Path to the unstripped libchrome.so file.
       tools_prefix: Prefix for arch-specific version of binary utility tools.
+      dump_sis: Whether or not to run dump-static-initializers.py and print
+          the list of static initializers to stdout.
      Returns:
        The number of static initializers found.
   """
@@ -639,14 +640,17 @@
   with Unzip(apk_path, filename=apk_so_name) as unzipped_so:
     _VerifyLibBuildIdsMatch(tools_prefix, unzipped_so, so_with_symbols_path)
     readelf_si_count = CountStaticInitializers(unzipped_so, tools_prefix)
-  sis, dump_si_count = GetStaticInitializers(so_with_symbols_path, tools_prefix)
-  print ('Found %s files with static initializers using readelf\n'
-         'Found %s files with static initializers using '
-         'dump-static-initializers') % (readelf_si_count, dump_si_count)
-  print '\n'.join(sis)
+  if dump_sis:
+    sis, dump_si_count = GetStaticInitializers(
+        so_with_symbols_path, tools_prefix)
+    print ('Found %s files with static initializers using readelf\n'
+           'Found %s files with static initializers using '
+           'dump-static-initializers') % (readelf_si_count, dump_si_count)
+    print '\n'.join(sis)
 
   return readelf_si_count
 
+
 def _FormatBytes(byts):
   """Pretty-print a number of bytes."""
   if byts > 2**20.0:
@@ -738,9 +742,9 @@
   argparser.add_argument('--no-output-dir', action='store_true',
                          help='Skip all measurements that rely on having '
                          'output-dir')
-  argparser.add_argument('--no-static-initializer-check', action='store_false',
-                         dest='static_initializer_check', default=True,
-                         help='Skip checking for static initializers')
+  argparser.add_argument('--dump-static-initializers', action='store_true',
+                         help='Run dump-static-initializers.py to get the list'
+                         'of static initializers (slow).')
   argparser.add_argument('-d', '--device',
                          help='Dummy option for perf runner.')
   argparser.add_argument('--estimate-patch-size', action='store_true',
@@ -777,9 +781,9 @@
                             args.reference_apk_bucket, chartjson=chartjson)
   if not args.no_output_dir:
     PrintPakAnalysis(args.apk, args.min_pak_resource_size)
-    if args.static_initializer_check:
-      _PrintStaticInitializersCountFromApk(
-          args.apk, tools_prefix, chartjson=chartjson)
+    _PrintStaticInitializersCountFromApk(
+        args.apk, tools_prefix, args.dump_static_initializers,
+        chartjson=chartjson)
   if chartjson:
     results_path = os.path.join(args.output_dir, 'results-chart.json')
     logging.critical('Dumping json to %s', results_path)
diff --git a/build/config/linux/gtk2/BUILD.gn b/build/config/linux/gtk2/BUILD.gn
index 58af02a..010d592d 100644
--- a/build/config/linux/gtk2/BUILD.gn
+++ b/build/config/linux/gtk2/BUILD.gn
@@ -26,7 +26,6 @@
 # parts that explicitly need GTK2 are whitelisted on this target.
 group("gtk2") {
   visibility = [
-    "//gpu/gles2_conform_support:gles2_conform_test_windowless",
     "//build/config/linux/gtk",
     "//chrome/browser/ui/libgtkui:*",
   ]
diff --git a/cc/surfaces/direct_compositor_frame_sink_unittest.cc b/cc/surfaces/direct_compositor_frame_sink_unittest.cc
index f295ab0..a56be81 100644
--- a/cc/surfaces/direct_compositor_frame_sink_unittest.cc
+++ b/cc/surfaces/direct_compositor_frame_sink_unittest.cc
@@ -56,13 +56,13 @@
         base::MakeUnique<DelayBasedTimeSource>(task_runner_.get())));
 
     int max_frames_pending = 2;
-    std::unique_ptr<DisplayScheduler> scheduler(
-        new DisplayScheduler(task_runner_.get(), max_frames_pending));
+    std::unique_ptr<DisplayScheduler> scheduler(new DisplayScheduler(
+        begin_frame_source_.get(), task_runner_.get(), max_frames_pending));
 
     display_.reset(new Display(
         &bitmap_manager_, &gpu_memory_buffer_manager_, RendererSettings(),
-        kArbitraryFrameSinkId, begin_frame_source_.get(),
-        std::move(display_output_surface), std::move(scheduler),
+        kArbitraryFrameSinkId, std::move(display_output_surface),
+        std::move(scheduler),
         base::MakeUnique<TextureMailboxDeleter>(task_runner_.get())));
     compositor_frame_sink_.reset(new TestDirectCompositorFrameSink(
         kArbitraryFrameSinkId, &surface_manager_, display_.get(),
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
index afcc23d..a9c5358e 100644
--- a/cc/surfaces/display.cc
+++ b/cc/surfaces/display.cc
@@ -37,7 +37,6 @@
                  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
                  const RendererSettings& settings,
                  const FrameSinkId& frame_sink_id,
-                 BeginFrameSource* begin_frame_source,
                  std::unique_ptr<OutputSurface> output_surface,
                  std::unique_ptr<DisplayScheduler> scheduler,
                  std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter)
@@ -45,17 +44,13 @@
       gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
       settings_(settings),
       frame_sink_id_(frame_sink_id),
-      begin_frame_source_(begin_frame_source),
       output_surface_(std::move(output_surface)),
       scheduler_(std::move(scheduler)),
       texture_mailbox_deleter_(std::move(texture_mailbox_deleter)) {
   DCHECK(output_surface_);
-  DCHECK_EQ(!scheduler_, !begin_frame_source_);
   DCHECK(frame_sink_id_.is_valid());
-  if (scheduler_) {
+  if (scheduler_)
     scheduler_->SetClient(this);
-    scheduler_->SetBeginFrameSource(begin_frame_source);
-  }
 }
 
 Display::~Display() {
@@ -63,9 +58,8 @@
   if (client_) {
     if (auto* context = output_surface_->context_provider())
       context->SetLostContextCallback(base::Closure());
-    if (begin_frame_source_)
-      surface_manager_->UnregisterBeginFrameSource(begin_frame_source_);
-    surface_manager_->RemoveObserver(this);
+    if (scheduler_)
+      surface_manager_->RemoveObserver(scheduler_.get());
   }
   if (aggregator_) {
     for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
@@ -82,15 +76,8 @@
   DCHECK(surface_manager);
   client_ = client;
   surface_manager_ = surface_manager;
-
-  surface_manager_->AddObserver(this);
-
-  // This must be done in Initialize() so that the caller can delay this until
-  // they are ready to receive a BeginFrameSource.
-  if (begin_frame_source_) {
-    surface_manager_->RegisterBeginFrameSource(begin_frame_source_,
-                                               frame_sink_id_);
-  }
+  if (scheduler_)
+    surface_manager_->AddObserver(scheduler_.get());
 
   output_surface_->BindToClient(this);
   InitializeRenderer();
@@ -384,12 +371,12 @@
   if (scheduler_) {
     BeginFrameAck ack;
     ack.has_damage = true;
-    scheduler_->SurfaceDamaged(current_surface_id_, ack, true);
+    scheduler_->ProcessSurfaceDamage(current_surface_id_, ack, true);
   }
 }
 
-bool Display::OnSurfaceDamaged(const SurfaceId& surface_id,
-                               const BeginFrameAck& ack) {
+bool Display::SurfaceDamaged(const SurfaceId& surface_id,
+                             const BeginFrameAck& ack) {
   bool display_damaged = false;
   if (ack.has_damage) {
     if (aggregator_ &&
@@ -409,11 +396,14 @@
     }
   }
 
-  if (scheduler_)
-    scheduler_->SurfaceDamaged(surface_id, ack, display_damaged);
   return display_damaged;
 }
 
+void Display::SurfaceDiscarded(const SurfaceId& surface_id) {
+  if (aggregator_)
+    aggregator_->ReleaseResources(surface_id);
+}
+
 bool Display::SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const {
   if (!surface_manager_)
     return false;
@@ -425,27 +415,6 @@
   return surface->HasUndrawnActiveFrame();
 }
 
-void Display::OnSurfaceCreated(const SurfaceInfo& surface_info) {
-  if (scheduler_)
-    scheduler_->SurfaceCreated(surface_info);
-}
-
-void Display::OnSurfaceDestroyed(const SurfaceId& surface_id) {
-  if (scheduler_)
-    scheduler_->SurfaceDestroyed(surface_id);
-}
-
-void Display::OnSurfaceDamageExpected(const SurfaceId& surface_id,
-                                      const BeginFrameArgs& args) {
-  if (scheduler_)
-    scheduler_->SurfaceDamageExpected(surface_id, args);
-}
-
-void Display::OnSurfaceDiscarded(const SurfaceId& surface_id) {
-  if (aggregator_)
-    aggregator_->ReleaseResources(surface_id);
-}
-
 const SurfaceId& Display::CurrentSurfaceId() {
   return current_surface_id_;
 }
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h
index 610588f..b96abb6 100644
--- a/cc/surfaces/display.h
+++ b/cc/surfaces/display.h
@@ -32,7 +32,6 @@
 
 namespace cc {
 
-class BeginFrameSource;
 class DirectRenderer;
 class DisplayClient;
 class OutputSurface;
@@ -46,8 +45,7 @@
 // (OutputSurface). The client is responsible for creating and sizing the
 // surface IDs used to draw into the display and deciding when to draw.
 class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient,
-                                   public OutputSurfaceClient,
-                                   public SurfaceObserver {
+                                   public OutputSurfaceClient {
  public:
   // The |begin_frame_source| and |scheduler| may be null (together). In that
   // case, DrawAndSwap must be called externally when needed.
@@ -55,7 +53,6 @@
           gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
           const RendererSettings& settings,
           const FrameSinkId& frame_sink_id,
-          BeginFrameSource* begin_frame_source,
           std::unique_ptr<OutputSurface> output_surface,
           std::unique_ptr<DisplayScheduler> scheduler,
           std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter);
@@ -78,6 +75,9 @@
   // DisplaySchedulerClient implementation.
   bool DrawAndSwap() override;
   bool SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const override;
+  bool SurfaceDamaged(const SurfaceId& surface_id,
+                      const BeginFrameAck& ack) override;
+  void SurfaceDiscarded(const SurfaceId& surface_id) override;
 
   // OutputSurfaceClient implementation.
   void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override;
@@ -85,15 +85,6 @@
   void DidReceiveTextureInUseResponses(
       const gpu::TextureInUseResponses& responses) override;
 
-  // SurfaceObserver implementation.
-  bool OnSurfaceDamaged(const SurfaceId& surface,
-                        const BeginFrameAck& ack) override;
-  void OnSurfaceCreated(const SurfaceInfo& surface_info) override;
-  void OnSurfaceDiscarded(const SurfaceId& surface_id) override;
-  void OnSurfaceDestroyed(const SurfaceId& surface_id) override;
-  void OnSurfaceDamageExpected(const SurfaceId& surface_id,
-                               const BeginFrameArgs& args) override;
-
   bool has_scheduler() const { return !!scheduler_; }
   DirectRenderer* renderer_for_testing() const { return renderer_.get(); }
 
@@ -120,9 +111,6 @@
   bool swapped_since_resize_ = false;
   bool output_is_secure_ = false;
 
-  // The begin_frame_source_ is not owned here, and also often known by the
-  // output_surface_ and the scheduler_.
-  BeginFrameSource* begin_frame_source_;
   std::unique_ptr<OutputSurface> output_surface_;
   std::unique_ptr<DisplayScheduler> scheduler_;
   std::unique_ptr<ResourceProvider> resource_provider_;
diff --git a/cc/surfaces/display_scheduler.cc b/cc/surfaces/display_scheduler.cc
index 8265b87..75ace10c2 100644
--- a/cc/surfaces/display_scheduler.cc
+++ b/cc/surfaces/display_scheduler.cc
@@ -14,10 +14,11 @@
 
 namespace cc {
 
-DisplayScheduler::DisplayScheduler(base::SingleThreadTaskRunner* task_runner,
+DisplayScheduler::DisplayScheduler(BeginFrameSource* begin_frame_source,
+                                   base::SingleThreadTaskRunner* task_runner,
                                    int max_pending_swaps)
     : client_(nullptr),
-      begin_frame_source_(nullptr),
+      begin_frame_source_(begin_frame_source),
       task_runner_(task_runner),
       inside_surface_damaged_(false),
       visible_(false),
@@ -44,11 +45,6 @@
   client_ = client;
 }
 
-void DisplayScheduler::SetBeginFrameSource(
-    BeginFrameSource* begin_frame_source) {
-  begin_frame_source_ = begin_frame_source;
-}
-
 void DisplayScheduler::SetVisible(bool visible) {
   if (visible_ == visible)
     return;
@@ -91,15 +87,15 @@
   root_surface_id_ = root_surface_id;
   BeginFrameAck ack;
   ack.has_damage = true;
-  SurfaceDamaged(root_surface_id, ack, true);
+  ProcessSurfaceDamage(root_surface_id, ack, true);
 }
 
 // Indicates that there was damage to one of the surfaces.
 // Has some logic to wait for multiple active surfaces before
 // triggering the deadline.
-void DisplayScheduler::SurfaceDamaged(const SurfaceId& surface_id,
-                                      const BeginFrameAck& ack,
-                                      bool display_damaged) {
+void DisplayScheduler::ProcessSurfaceDamage(const SurfaceId& surface_id,
+                                            const BeginFrameAck& ack,
+                                            bool display_damaged) {
   TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id",
                surface_id.ToString());
 
@@ -135,33 +131,6 @@
     ScheduleBeginFrameDeadline();
 }
 
-void DisplayScheduler::SurfaceCreated(const SurfaceInfo& surface_info) {
-  SurfaceId surface_id = surface_info.id();
-  DCHECK(!base::ContainsKey(surface_states_, surface_id));
-  surface_states_[surface_id] = SurfaceBeginFrameState();
-}
-
-void DisplayScheduler::SurfaceDestroyed(const SurfaceId& surface_id) {
-  auto it = surface_states_.find(surface_id);
-  if (it == surface_states_.end())
-    return;
-  surface_states_.erase(it);
-  if (UpdateHasPendingSurfaces())
-    ScheduleBeginFrameDeadline();
-}
-
-void DisplayScheduler::SurfaceDamageExpected(const SurfaceId& surface_id,
-                                             const BeginFrameArgs& args) {
-  TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamageExpected", "surface_id",
-               surface_id.ToString());
-  auto it = surface_states_.find(surface_id);
-  if (it == surface_states_.end())
-    return;
-  it->second.last_args = args;
-  if (UpdateHasPendingSurfaces())
-    ScheduleBeginFrameDeadline();
-}
-
 bool DisplayScheduler::UpdateHasPendingSurfaces() {
   // If we're not currently inside a deadline interval, we will call
   // UpdateHasPendingSurfaces() again during OnBeginFrameImpl().
@@ -306,6 +275,45 @@
     NOTIMPLEMENTED();
 }
 
+void DisplayScheduler::OnSurfaceCreated(const SurfaceInfo& surface_info) {
+  SurfaceId surface_id = surface_info.id();
+  DCHECK(!base::ContainsKey(surface_states_, surface_id));
+  surface_states_[surface_id] = SurfaceBeginFrameState();
+}
+
+void DisplayScheduler::OnSurfaceDestroyed(const SurfaceId& surface_id) {
+  auto it = surface_states_.find(surface_id);
+  if (it == surface_states_.end())
+    return;
+  surface_states_.erase(it);
+  if (UpdateHasPendingSurfaces())
+    ScheduleBeginFrameDeadline();
+}
+
+bool DisplayScheduler::OnSurfaceDamaged(const SurfaceId& surface_id,
+                                        const BeginFrameAck& ack) {
+  bool damaged = client_->SurfaceDamaged(surface_id, ack);
+  ProcessSurfaceDamage(surface_id, ack, damaged);
+
+  return damaged;
+}
+
+void DisplayScheduler::OnSurfaceDiscarded(const SurfaceId& surface_id) {
+  client_->SurfaceDiscarded(surface_id);
+}
+
+void DisplayScheduler::OnSurfaceDamageExpected(const SurfaceId& surface_id,
+                                               const BeginFrameArgs& args) {
+  TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamageExpected", "surface_id",
+               surface_id.ToString());
+  auto it = surface_states_.find(surface_id);
+  if (it == surface_states_.end())
+    return;
+  it->second.last_args = args;
+  if (UpdateHasPendingSurfaces())
+    ScheduleBeginFrameDeadline();
+}
+
 base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() {
   if (output_surface_lost_) {
     TRACE_EVENT_INSTANT0("cc", "Lost output surface", TRACE_EVENT_SCOPE_THREAD);
diff --git a/cc/surfaces/display_scheduler.h b/cc/surfaces/display_scheduler.h
index 536c55b..764757b 100644
--- a/cc/surfaces/display_scheduler.h
+++ b/cc/surfaces/display_scheduler.h
@@ -15,6 +15,7 @@
 #include "cc/output/renderer_settings.h"
 #include "cc/scheduler/begin_frame_source.h"
 #include "cc/surfaces/surface_id.h"
+#include "cc/surfaces/surface_observer.h"
 #include "cc/surfaces/surfaces_export.h"
 
 namespace cc {
@@ -28,39 +29,48 @@
 
   virtual bool DrawAndSwap() = 0;
   virtual bool SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const = 0;
+  virtual bool SurfaceDamaged(const SurfaceId& surface_id,
+                              const BeginFrameAck& ack) = 0;
+  virtual void SurfaceDiscarded(const SurfaceId& surface_id) = 0;
 };
 
-class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase {
+class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase,
+                                            public SurfaceObserver {
  public:
-  DisplayScheduler(base::SingleThreadTaskRunner* task_runner,
+  DisplayScheduler(BeginFrameSource* begin_frame_source,
+                   base::SingleThreadTaskRunner* task_runner,
                    int max_pending_swaps);
   ~DisplayScheduler() override;
 
   void SetClient(DisplaySchedulerClient* client);
-  void SetBeginFrameSource(BeginFrameSource* begin_frame_source);
 
   void SetVisible(bool visible);
   void SetRootSurfaceResourcesLocked(bool locked);
   void ForceImmediateSwapIfPossible();
   virtual void DisplayResized();
   virtual void SetNewRootSurface(const SurfaceId& root_surface_id);
-  virtual void SurfaceDamaged(const SurfaceId& surface_id,
-                              const BeginFrameAck& ack,
-                              bool display_damaged);
-  void SurfaceCreated(const SurfaceInfo& surface_info);
-  void SurfaceDestroyed(const SurfaceId& surface_id);
-  void SurfaceDamageExpected(const SurfaceId& surface_id,
-                             const BeginFrameArgs& args);
+  virtual void ProcessSurfaceDamage(const SurfaceId& surface_id,
+                                    const BeginFrameAck& ack,
+                                    bool display_damaged);
 
   virtual void DidSwapBuffers();
   void DidReceiveSwapBuffersAck();
 
   void OutputSurfaceLost();
 
-  // BeginFrameObserverBase implementation
+  // BeginFrameObserverBase implementation.
   bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override;
   void OnBeginFrameSourcePausedChanged(bool paused) override;
 
+  // SurfaceObserver implementation.
+  void OnSurfaceCreated(const SurfaceInfo& surface_info) override;
+  void OnSurfaceDestroyed(const SurfaceId& surface_id) override;
+  bool OnSurfaceDamaged(const SurfaceId& surface_id,
+                        const BeginFrameAck& ack) override;
+  void OnSurfaceDiscarded(const SurfaceId& surface_id) override;
+  void OnSurfaceDamageExpected(const SurfaceId& surface_id,
+                               const BeginFrameArgs& args) override;
+
  protected:
   base::TimeTicks DesiredBeginFrameDeadlineTime();
   virtual void ScheduleBeginFrameDeadline();
diff --git a/cc/surfaces/display_scheduler_unittest.cc b/cc/surfaces/display_scheduler_unittest.cc
index 68e80a00..99fd6b6 100644
--- a/cc/surfaces/display_scheduler_unittest.cc
+++ b/cc/surfaces/display_scheduler_unittest.cc
@@ -45,6 +45,13 @@
     return base::ContainsKey(undrawn_surfaces_, surface_id);
   }
 
+  bool SurfaceDamaged(const SurfaceId& surface_id,
+                      const BeginFrameAck& ack) override {
+    return false;
+  }
+
+  void SurfaceDiscarded(const SurfaceId& surface_id) override {}
+
   int draw_and_swap_count() const { return draw_and_swap_count_; }
 
   void SetNextDrawAndSwapFails() { next_draw_and_swap_fails_ = true; }
@@ -62,12 +69,11 @@
 class TestDisplayScheduler : public DisplayScheduler {
  public:
   TestDisplayScheduler(BeginFrameSource* begin_frame_source,
+                       SurfaceManager* surface_manager,
                        base::SingleThreadTaskRunner* task_runner,
                        int max_pending_swaps)
-      : DisplayScheduler(task_runner, max_pending_swaps),
-        scheduler_begin_frame_deadline_count_(0) {
-    SetBeginFrameSource(begin_frame_source);
-  }
+      : DisplayScheduler(begin_frame_source, task_runner, max_pending_swaps),
+        scheduler_begin_frame_deadline_count_(0) {}
 
   base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
     return DesiredBeginFrameDeadlineTime();
@@ -106,13 +112,17 @@
       : fake_begin_frame_source_(0.f, false),
         task_runner_(new base::NullTaskRunner),
         scheduler_(&fake_begin_frame_source_,
+                   &surface_manager_,
                    task_runner_.get(),
                    kMaxPendingSwaps) {
     now_src_.Advance(base::TimeDelta::FromMicroseconds(10000));
+    surface_manager_.AddObserver(&scheduler_);
     scheduler_.SetClient(&client_);
   }
 
-  ~DisplaySchedulerTest() override {}
+  ~DisplaySchedulerTest() override {
+    surface_manager_.RemoveObserver(&scheduler_);
+  }
 
   void SetUp() override { scheduler_.SetRootSurfaceResourcesLocked(false); }
 
@@ -124,12 +134,13 @@
         BEGINFRAME_FROM_HERE, &now_src_);
     fake_begin_frame_source_.TestOnBeginFrame(last_begin_frame_args_);
     for (const SurfaceId& surface : observing_surfaces)
-      scheduler_.SurfaceDamageExpected(surface, last_begin_frame_args_);
+      scheduler_.OnSurfaceDamageExpected(surface, last_begin_frame_args_);
   }
 
   void SurfaceDamaged(const SurfaceId& surface_id) {
     client_.SurfaceDamaged(surface_id);
-    scheduler_.SurfaceDamaged(surface_id, AckForCurrentBeginFrame(), true);
+    scheduler_.ProcessSurfaceDamage(surface_id, AckForCurrentBeginFrame(),
+                                    true);
   }
 
  protected:
@@ -148,6 +159,7 @@
 
   base::SimpleTestTickClock now_src_;
   scoped_refptr<base::NullTaskRunner> task_runner_;
+  SurfaceManager surface_manager_;
   FakeDisplaySchedulerClient client_;
   TestDisplayScheduler scheduler_;
 };
@@ -167,7 +179,7 @@
 
   // Go trough an initial BeginFrame cycle with the root surface.
   AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id1, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id1);
   scheduler_.BeginFrameDeadlineForTest();
 
@@ -175,13 +187,13 @@
   // for a new root surface.
   AdvanceTimeAndBeginFrameForTest({root_surface_id1});
   late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
   SurfaceDamaged(sid1);
   EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
   scheduler_.DisplayResized();
   EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.SurfaceDestroyed(root_surface_id1);
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id2, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceDestroyed(root_surface_id1);
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id2, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id2);
   EXPECT_GE(now_src().NowTicks(),
             scheduler_.DesiredBeginFrameDeadlineTimeForTest());
@@ -210,7 +222,7 @@
 
   // Go trough an initial BeginFrame cycle with the root surface.
   AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
   scheduler_.BeginFrameDeadlineForTest();
 
@@ -218,7 +230,7 @@
   // for a new root surface.
   AdvanceTimeAndBeginFrameForTest({root_surface_id});
   late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
   SurfaceDamaged(sid1);
   EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
   scheduler_.DisplayResized();
@@ -251,9 +263,9 @@
   scheduler_.SetVisible(true);
 
   // Create surfaces and set the root surface.
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(sid2, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid2, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
 
   // Set surface1 as active via SurfaceDamageExpected().
@@ -292,7 +304,7 @@
             scheduler_.DesiredBeginFrameDeadlineTimeForTest());
   BeginFrameAck ack = AckForCurrentBeginFrame();
   ack.has_damage = false;
-  scheduler_.SurfaceDamaged(sid1, ack, false);
+  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
   EXPECT_GE(now_src().NowTicks(),
             scheduler_.DesiredBeginFrameDeadlineTimeForTest());
   scheduler_.BeginFrameDeadlineForTest();
@@ -303,12 +315,12 @@
 
   // SurfaceDamage with |!display_damaged| does not affect needs_draw and
   // scheduler stays idle.
-  scheduler_.SurfaceDamaged(sid1, AckForCurrentBeginFrame(), false);
+  scheduler_.ProcessSurfaceDamage(sid1, AckForCurrentBeginFrame(), false);
   EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
 
   // Deadline should trigger early if child surfaces are idle and
   // we get damage on the root surface.
-  scheduler_.SurfaceDamageExpected(root_surface_id, last_begin_frame_args_);
+  scheduler_.OnSurfaceDamageExpected(root_surface_id, last_begin_frame_args_);
   EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
   SurfaceDamaged(root_surface_id);
   EXPECT_GE(now_src().NowTicks(),
@@ -326,8 +338,8 @@
   scheduler_.SetVisible(true);
 
   // Create surfaces and set the root surface.
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
 
   // DrawAndSwap normally.
@@ -395,8 +407,8 @@
                  LocalSurfaceId(2, base::UnguessableToken::Create()));
 
   // Create surfaces and set the root surface.
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
   scheduler_.SetVisible(true);
   EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
@@ -452,8 +464,8 @@
   scheduler_.SetVisible(true);
 
   // Create surfaces and set the root surface.
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
 
   // DrawAndSwap normally.
@@ -483,8 +495,8 @@
   scheduler_.SetVisible(true);
 
   // Create surfaces and set the root surface.
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
 
   // DrawAndSwap normally.
@@ -537,9 +549,9 @@
   scheduler_.SetVisible(true);
 
   // Create surfaces and set the root surface.
-  scheduler_.SurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(sid2, 1.0f, gfx::Size()));
-  scheduler_.SurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid1, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(sid2, 1.0f, gfx::Size()));
+  scheduler_.OnSurfaceCreated(SurfaceInfo(root_surface_id, 1.0f, gfx::Size()));
   scheduler_.SetNewRootSurface(root_surface_id);
 
   // Set surface 1 and 2 as active.
diff --git a/cc/surfaces/display_unittest.cc b/cc/surfaces/display_unittest.cc
index 25868c50..4bd0f4e 100644
--- a/cc/surfaces/display_unittest.cc
+++ b/cc/surfaces/display_unittest.cc
@@ -47,8 +47,9 @@
 
 class TestDisplayScheduler : public DisplayScheduler {
  public:
-  explicit TestDisplayScheduler(base::SingleThreadTaskRunner* task_runner)
-      : DisplayScheduler(task_runner, 1),
+  explicit TestDisplayScheduler(BeginFrameSource* begin_frame_source,
+                                base::SingleThreadTaskRunner* task_runner)
+      : DisplayScheduler(begin_frame_source, task_runner, 1),
         damaged(false),
         display_resized_(false),
         has_new_root_surface(false),
@@ -62,9 +63,9 @@
     has_new_root_surface = true;
   }
 
-  void SurfaceDamaged(const SurfaceId& surface_id,
-                      const BeginFrameAck& ack,
-                      bool display_damaged) override {
+  void ProcessSurfaceDamage(const SurfaceId& surface_id,
+                            const BeginFrameAck& ack,
+                            bool display_damaged) override {
     if (display_damaged) {
       damaged = true;
       needs_draw_ = true;
@@ -114,28 +115,35 @@
       output_surface = FakeOutputSurface::CreateSoftware(std::move(device));
     }
     output_surface_ = output_surface.get();
-    auto scheduler = base::MakeUnique<TestDisplayScheduler>(task_runner_.get());
+    auto scheduler = base::MakeUnique<TestDisplayScheduler>(
+        begin_frame_source_.get(), task_runner_.get());
     scheduler_ = scheduler.get();
     display_ = CreateDisplay(settings, kArbitraryFrameSinkId,
-                             begin_frame_source_.get(), std::move(scheduler),
-                             std::move(output_surface));
+                             std::move(scheduler), std::move(output_surface));
+    manager_.RegisterBeginFrameSource(begin_frame_source_.get(),
+                                      kArbitraryFrameSinkId);
   }
 
   std::unique_ptr<Display> CreateDisplay(
       const RendererSettings& settings,
       const FrameSinkId& frame_sink_id,
-      BeginFrameSource* begin_frame_source,
       std::unique_ptr<DisplayScheduler> scheduler,
       std::unique_ptr<OutputSurface> output_surface) {
     auto display = base::MakeUnique<Display>(
         &shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
-        settings, frame_sink_id, begin_frame_source, std::move(output_surface),
+        settings, frame_sink_id, std::move(output_surface),
         std::move(scheduler),
         base::MakeUnique<TextureMailboxDeleter>(task_runner_.get()));
     display->SetVisible(true);
     return display;
   }
 
+  void TearDownDisplay() {
+    // Only call UnregisterBeginFrameSource if SetupDisplay has been called.
+    if (begin_frame_source_)
+      manager_.UnregisterBeginFrameSource(begin_frame_source_.get());
+  }
+
  protected:
   void SubmitCompositorFrame(RenderPassList* pass_list,
                              const LocalSurfaceId& local_surface_id) {
@@ -424,6 +432,7 @@
               software_output_device_->damage_rect());
     EXPECT_EQ(0u, output_surface_->last_sent_frame()->latency_info.size());
   }
+  TearDownDisplay();
 }
 
 class MockedContext : public TestWebGraphicsContext3D {
@@ -497,6 +506,7 @@
   EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
   display_->Resize(gfx::Size(250, 250));
   testing::Mock::VerifyAndClearExpectations(context_ptr);
+  TearDownDisplay();
 }
 
 class CountLossDisplayClient : public StubDisplayClient {
@@ -523,6 +533,7 @@
       GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
   output_surface_->context_provider()->ContextGL()->Flush();
   EXPECT_EQ(1, client.loss_count());
+  TearDownDisplay();
 }
 
 // Regression test for https://crbug.com/727162: Submitting a CompositorFrame to
@@ -544,14 +555,15 @@
       true /* handles_frame_sink_id_invalidation */,
       true /* needs_sync_points */);
   auto begin_frame_source2 = base::MakeUnique<StubBeginFrameSource>();
-  auto scheduler_for_display2 =
-      base::MakeUnique<TestDisplayScheduler>(task_runner_.get());
+  auto scheduler_for_display2 = base::MakeUnique<TestDisplayScheduler>(
+      begin_frame_source2.get(), task_runner_.get());
   TestDisplayScheduler* scheduler2 = scheduler_for_display2.get();
-  auto display2 =
-      CreateDisplay(settings, kAnotherFrameSinkId, begin_frame_source2.get(),
-                    std::move(scheduler_for_display2),
-                    FakeOutputSurface::CreateSoftware(
-                        base::MakeUnique<TestSoftwareOutputDevice>()));
+  auto display2 = CreateDisplay(
+      settings, kAnotherFrameSinkId, std::move(scheduler_for_display2),
+      FakeOutputSurface::CreateSoftware(
+          base::MakeUnique<TestSoftwareOutputDevice>()));
+  manager_.RegisterBeginFrameSource(begin_frame_source2.get(),
+                                    kAnotherFrameSinkId);
   StubDisplayClient client2;
   display2->Initialize(&client2, &manager_);
   display2->SetLocalSurfaceId(local_surface_id, 1.f);
@@ -577,6 +589,8 @@
   // Should have damaged only display_ but not display2.
   EXPECT_TRUE(scheduler_->damaged);
   EXPECT_FALSE(scheduler2->damaged);
+  manager_.UnregisterBeginFrameSource(begin_frame_source2.get());
+  TearDownDisplay();
 }
 
 }  // namespace
diff --git a/cc/test/test_compositor_frame_sink.cc b/cc/test/test_compositor_frame_sink.cc
index 440b5d5..6b4a5a5 100644
--- a/cc/test/test_compositor_frame_sink.cc
+++ b/cc/test/test_compositor_frame_sink.cc
@@ -79,15 +79,14 @@
                                             renderer_settings_.refresh_rate));
     }
     scheduler.reset(new DisplayScheduler(
-        task_runner_.get(),
+        begin_frame_source_.get(), task_runner_.get(),
         display_output_surface->capabilities().max_frames_pending));
   }
 
-  display_.reset(
-      new Display(shared_bitmap_manager(), gpu_memory_buffer_manager(),
-                  renderer_settings_, frame_sink_id_, begin_frame_source_.get(),
-                  std::move(display_output_surface), std::move(scheduler),
-                  base::MakeUnique<TextureMailboxDeleter>(task_runner_.get())));
+  display_ = base::MakeUnique<Display>(
+      shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings_,
+      frame_sink_id_, std::move(display_output_surface), std::move(scheduler),
+      base::MakeUnique<TextureMailboxDeleter>(task_runner_.get()));
 
   // We want the Display's OutputSurface to hear about lost context, and when
   // this shares a context with it we should not be listening for lost context
@@ -102,7 +101,10 @@
       this, surface_manager_.get(), frame_sink_id_, is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
   client_->SetBeginFrameSource(&external_begin_frame_source_);
-
+  if (begin_frame_source_) {
+    surface_manager_->RegisterBeginFrameSource(begin_frame_source_.get(),
+                                               frame_sink_id_);
+  }
   display_->Initialize(this, surface_manager_.get());
   display_->renderer_for_testing()->SetEnlargePassTextureAmountForTesting(
       enlarge_pass_texture_amount_);
@@ -111,6 +113,8 @@
 }
 
 void TestCompositorFrameSink::DetachFromClient() {
+  if (begin_frame_source_)
+    surface_manager_->UnregisterBeginFrameSource(begin_frame_source_.get());
   client_->SetBeginFrameSource(nullptr);
   support_ = nullptr;
   display_ = nullptr;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 7d3936d8..6cba336 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1680,7 +1680,7 @@
 
   java_cpp_enum("sad_tab_event_enum_javagen") {
     sources = [
-      "browser/ui/sad_tab.cc",
+      "//components/ui_metrics/sadtab_metrics_types.h",
     ]
   }
 
@@ -1716,6 +1716,15 @@
       "//content/public/common:service_names",
       "//services/service_manager/embedder",
     ]
+
+    # Explicit dependency required for JNI registration to be able to
+    # find the native side functions.
+    if (is_android && is_component_build) {
+      deps += [
+        "//device/generic_sensor",
+        "//device/sensors",
+      ]
+    }
   }
 }
 
diff --git a/chrome/android/java/res/drawable-hdpi/context_menu_search.png b/chrome/android/java/res/drawable-hdpi/context_menu_search.png
new file mode 100644
index 0000000..1f468b2
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/context_menu_search.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/context_menu_search.png b/chrome/android/java/res/drawable-mdpi/context_menu_search.png
new file mode 100644
index 0000000..970e41ec
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/context_menu_search.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/context_menu_search.png b/chrome/android/java/res/drawable-xhdpi/context_menu_search.png
new file mode 100644
index 0000000..7aba439
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/context_menu_search.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/context_menu_search.png b/chrome/android/java/res/drawable-xxhdpi/context_menu_search.png
new file mode 100644
index 0000000..f6a5e67d
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/context_menu_search.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/context_menu_search.png b/chrome/android/java/res/drawable-xxxhdpi/context_menu_search.png
new file mode 100644
index 0000000..077b988
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/context_menu_search.png
Binary files differ
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index ee5f48a0..fca1505 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -189,6 +189,7 @@
     public static final String NTP_OFFLINE_PAGES_FEATURE_NAME = "NTPOfflinePages";
     public static final String NTP_SHOW_GOOGLE_G_IN_OMNIBOX = "NTPShowGoogleGInOmnibox";
     public static final String NTP_SNIPPETS_INCREASED_VISIBILITY = "NTPSnippetsIncreasedVisibility";
+    public static final String PAY_WITH_GOOGLE_V1 = "PayWithGoogleV1";
     public static final String SERVICE_WORKER_PAYMENT_APPS = "ServiceWorkerPaymentApps";
     public static final String TAB_REPARENTING = "TabReparenting";
     public static final String VIDEO_PERSISTENCE = "VideoPersistence";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
index 77f08a9..2c29f8f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenu.java
@@ -159,7 +159,7 @@
     void show(Context context, final View anchorView, boolean isByPermanentButton,
             int screenRotation, Rect visibleDisplayFrame, int screenHeight,
             @IdRes int footerResourceId, Integer highlightedItemId) {
-        mPopup = new PopupWindow(context, null, android.R.attr.popupMenuStyle);
+        mPopup = new PopupWindow(context);
         mPopup.setFocusable(true);
         mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
index 422b55b3..d63ccb95 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
@@ -51,7 +51,7 @@
             R.id.contextmenu_open_image),
     OPEN_IMAGE_IN_NEW_TAB(R.drawable.context_menu_new_tab,
             R.string.contextmenu_open_image_in_new_tab, R.id.contextmenu_open_image_in_new_tab),
-    SEARCH_BY_IMAGE(R.drawable.googleg, R.string.contextmenu_search_web_for_image,
+    SEARCH_BY_IMAGE(R.drawable.context_menu_search, R.string.contextmenu_search_web_for_image,
             R.id.contextmenu_search_by_image),
     SHARE_IMAGE(R.drawable.ic_share_white_24dp, R.string.contextmenu_share_image,
             R.id.contextmenu_share_image),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
index 6653d4d..630e4c9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
@@ -341,7 +341,12 @@
 
         mPayIntent.putExtras(buildExtras(id, merchantName, origin, iframeOrigin, certificateChain,
                 methodDataMap, total, displayItems, modifiers));
-        if (!window.showIntent(mPayIntent, this, R.string.payments_android_app_error)) {
+        try {
+            if (!window.showIntent(mPayIntent, this, R.string.payments_android_app_error)) {
+                notifyErrorInvokingPaymentApp();
+            }
+        } catch (SecurityException e) {
+            // Payment app does not have android:exported="true" on the PAY activity.
             notifyErrorInvokingPaymentApp();
         }
     }
@@ -559,11 +564,10 @@
             if (details == null) {
                 details = data.getExtras().getString(EXTRA_DEPRECATED_RESPONSE_INSTRUMENT_DETAILS);
             }
-            if (details == null) {
-                details = EMPTY_JSON_DATA;
-            }
-            mInstrumentDetailsCallback.onInstrumentDetailsReady(
-                    data.getExtras().getString(EXTRA_RESPONSE_METHOD_NAME), details);
+            if (details == null) details = EMPTY_JSON_DATA;
+            String methodName = data.getExtras().getString(EXTRA_RESPONSE_METHOD_NAME);
+            if (methodName == null) methodName = "";
+            mInstrumentDetailsCallback.onInstrumentDetailsReady(methodName, details);
         }
         mInstrumentDetailsCallback = null;
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
index c8e90d9..8803762 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -1629,6 +1629,9 @@
      */
     @Override
     public void onInstrumentDetailsReady(String methodName, String stringifiedDetails) {
+        assert methodName != null;
+        assert stringifiedDetails != null;
+
         if (mClient == null || mPaymentResponseHelper == null) return;
 
         // Record the payment method used to complete the transaction. If the payment method was an
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index 9747c715..0c0e0025 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -596,8 +596,8 @@
 
         // Listen to height changes on the root.
         root.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
-            /** The height of the screen minus the keyboard height. */
-            private float mHeightMinusKeyboard;
+            /** Whether or not the keyboard is currently showing. */
+            private boolean mIsKeyboardShowing;
 
             @Override
             public void onLayoutChange(View v, int left, int top, int right, int bottom,
@@ -609,7 +609,10 @@
                         mVisibleViewportRect);
                 int heightMinusKeyboard = Math.min(decorHeight, mVisibleViewportRect.height());
 
-                boolean keyboardHeightChanged = heightMinusKeyboard != mHeightMinusKeyboard;
+                boolean isKeyboardShowing =
+                        UiUtils.isKeyboardShowing(getContext(), BottomSheet.this);
+
+                boolean keyboardHeightChanged = isKeyboardShowing != mIsKeyboardShowing;
 
                 // Make sure the size of the layout actually changed.
                 if (!keyboardHeightChanged && bottom - top == oldBottom - oldTop
@@ -619,12 +622,13 @@
 
                 mContainerWidth = right - left;
                 mContainerHeight = bottom - top;
-                mHeightMinusKeyboard = heightMinusKeyboard;
-                int keyboardHeight = (int) (mContainerHeight - mHeightMinusKeyboard);
+                mIsKeyboardShowing = isKeyboardShowing;
+                int keyboardHeight =
+                        mIsKeyboardShowing ? (int) (mContainerHeight - heightMinusKeyboard) : 0;
                 updateSheetDimensions();
 
                 for (BottomSheetObserver o : mObservers) {
-                    o.onSheetLayout((int) mContainerHeight, (int) mHeightMinusKeyboard);
+                    o.onSheetLayout((int) mContainerHeight, heightMinusKeyboard);
                 }
 
                 // If the keyboard height changed, recompute the padding for the content area. This
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 8ce2826..99febc35 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -857,34 +857,34 @@
 
 #if defined(OS_ANDROID)
 const FeatureEntry::FeatureParam
-kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart[] = {
-  {"is_credit_card_icon_at_start", "true"}};
+    kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart[] = {
+        {"is_credit_card_icon_at_start", "true"}};
 
 const FeatureEntry::FeatureParam
-kAutofillCreditCardPopupLayoutFeatureVariationDropdownItemHeight[] = {
-  {"dropdown_item_height", "56"}};
+    kAutofillCreditCardPopupLayoutFeatureVariationDropdownItemHeight[] = {
+        {"dropdown_item_height", "56"}};
 
 const FeatureEntry::FeatureParam
-kAutofillCreditCardPopupLayoutFeatureVariationExpanded[] = {
-  {"is_credit_card_icon_at_start", "true"},
-  {"dropdown_item_height", "56"},
-  {"margin", "18"}};
+    kAutofillCreditCardPopupLayoutFeatureVariationExpanded[] = {
+        {"is_credit_card_icon_at_start", "true"},
+        {"dropdown_item_height", "56"},
+        {"margin", "18"}};
 
 const FeatureEntry::FeatureVariation
-kAutofillCreditCardPopupLayoutFeatureVariations[] = {
-    {"Display credit card icon at start",
-     kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart,
-     arraysize(kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart),
-     nullptr},
-    {"Increase dropdown item height",
-     kAutofillCreditCardPopupLayoutFeatureVariationDropdownItemHeight,
-     arraysize(
-         kAutofillCreditCardPopupLayoutFeatureVariationDropdownItemHeight),
-     nullptr},
-    {"Display credit card icon at start and increase dropdown item height",
-     kAutofillCreditCardPopupLayoutFeatureVariationExpanded,
-     arraysize(kAutofillCreditCardPopupLayoutFeatureVariationExpanded),
-     nullptr}};
+    kAutofillCreditCardPopupLayoutFeatureVariations[] = {
+        {"Display credit card icon at start",
+         kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart,
+         arraysize(kAutofillCreditCardPopupLayoutFeatureVariationIconAtStart),
+         nullptr},
+        {"Increase dropdown item height",
+         kAutofillCreditCardPopupLayoutFeatureVariationDropdownItemHeight,
+         arraysize(
+             kAutofillCreditCardPopupLayoutFeatureVariationDropdownItemHeight),
+         nullptr},
+        {"Display credit card icon at start and increase dropdown item height",
+         kAutofillCreditCardPopupLayoutFeatureVariationExpanded,
+         arraysize(kAutofillCreditCardPopupLayoutFeatureVariationExpanded),
+         nullptr}};
 
 const FeatureEntry::FeatureParam
     kAutofillKeyboardAccessoryFeatureVariationAnimationDuration[] = {
@@ -1772,14 +1772,6 @@
      flag_descriptions::kNotificationsNativeFlagDescription, kOsMac | kOsLinux,
      FEATURE_VALUE_TYPE(features::kNativeNotifications)},
 #endif  // ENABLE_NATIVE_NOTIFICATIONS
-#if defined(TOOLKIT_VIEWS)
-    {"disable-views-rect-based-targeting",
-     flag_descriptions::kViewsRectBasedTargetingName,
-     flag_descriptions::kViewsRectBasedTargetingDescription,
-     kOsCrOS | kOsWin | kOsLinux,
-     SINGLE_DISABLE_VALUE_TYPE(
-         views::switches::kDisableViewsRectBasedTargeting)},
-#endif  // TOOLKIT_VIEWS
 #if defined(OS_ANDROID)
     {"reader-mode-heuristics", flag_descriptions::kReaderModeHeuristicsName,
      flag_descriptions::kReaderModeHeuristicsDescription, kOsAndroid,
@@ -2572,6 +2564,9 @@
     {"android-payment-apps", flag_descriptions::kAndroidPaymentAppsName,
      flag_descriptions::kAndroidPaymentAppsDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kAndroidPaymentApps)},
+    {"pay-with-google-v1", flag_descriptions::kPayWithGoogleV1Name,
+     flag_descriptions::kPayWithGoogleV1Description, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kPayWithGoogleV1)},
     {"service-worker-payment-apps",
      flag_descriptions::kServiceWorkerPaymentAppsName,
      flag_descriptions::kServiceWorkerPaymentAppsDescription, kOsAndroid,
@@ -2775,7 +2770,7 @@
      flag_descriptions::kTouchscreenCalibrationName,
      flag_descriptions::kTouchscreenCalibrationDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchCalibrationSetting)},
-#endif // defined(OS_CHROMEOS)
+#endif  // defined(OS_CHROMEOS)
 #if defined(OS_CHROMEOS)
     {"team-drives", flag_descriptions::kTeamDrivesName,
      flag_descriptions::kTeamDrivesDescription, kOsCrOS,
@@ -2796,7 +2791,7 @@
      flag_descriptions::kForceEnableStylusToolsName,
      flag_descriptions::kForceEnableStylusToolsDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(ash::switches::kAshForceEnableStylusTools)},
-#endif // defined(OS_CHROMEOS)
+#endif  // defined(OS_CHROMEOS)
 
     {"enable-midi-manager-dynamic-instantiation",
      flag_descriptions::kEnableMidiManagerDynamicInstantiationName,
@@ -3142,8 +3137,7 @@
   // data-reduction-proxy-lo-fi and enable-data-reduction-proxy-lite-page
   // are only available for Chromium builds and the Canary/Dev/Beta channels.
   if ((!strcmp("data-reduction-proxy-lo-fi", entry.internal_name) ||
-       !strcmp("enable-data-reduction-proxy-lite-page",
-               entry.internal_name)) &&
+       !strcmp("enable-data-reduction-proxy-lite-page", entry.internal_name)) &&
       channel != version_info::Channel::BETA &&
       channel != version_info::Channel::DEV &&
       channel != version_info::Channel::CANARY &&
@@ -3193,7 +3187,7 @@
 // Records a set of FEATURE_VALUE_TYPE features (suffixed with ":enabled" or
 // "disabled", depending on their state).
 void ReportAboutFlagsHistogramFeatures(const std::string& uma_histogram_name,
-                                       const std::set<std::string>&features) {
+                                       const std::set<std::string>& features) {
   for (const std::string& feature : features) {
     int uma_id = GetSwitchUMAId(feature);
     DVLOG(1) << "ReportAboutFlagsHistogram(): histogram='" << uma_histogram_name
@@ -3285,10 +3279,9 @@
       base::HashMetricName(switch_name));
 }
 
-void ReportAboutFlagsHistogram(
-    const std::string& uma_histogram_name,
-    const std::set<std::string>& switches,
-    const std::set<std::string>& features) {
+void ReportAboutFlagsHistogram(const std::string& uma_histogram_name,
+                               const std::set<std::string>& switches,
+                               const std::set<std::string>& features) {
   ReportAboutFlagsHistogramSwitches(uma_histogram_name, switches);
   ReportAboutFlagsHistogramFeatures(uma_histogram_name, features);
 }
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 04a5a00..dbc9cb1 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -75,6 +75,7 @@
     &kNTPLaunchAfterInactivity,
     &kNTPOfflinePagesFeature,
     &NTPShowGoogleGInOmniboxFeature,
+    &kPayWithGoogleV1,
     &kPhysicalWebFeature,
     &kPhysicalWebSharing,
     &kSearchEnginePromoExistingDevice,
@@ -206,6 +207,9 @@
 const base::Feature NTPShowGoogleGInOmniboxFeature{
     "NTPShowGoogleGInOmnibox", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kPayWithGoogleV1{"PayWithGoogleV1",
+                                     base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kPhysicalWebFeature{"PhysicalWeb",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
@@ -245,8 +249,8 @@
 const base::Feature kWebVrAutopresent{"WebVrAutopresent",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 
-const base::Feature kWebVRCardboardSupport{
-    "WebVRCardboardSupport", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kWebVRCardboardSupport{"WebVRCardboardSupport",
+                                           base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kXGEOVisibleNetworks{"XGEOVisibleNetworks",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h
index d21d033..98c2b13 100644
--- a/chrome/browser/android/chrome_feature_list.h
+++ b/chrome/browser/android/chrome_feature_list.h
@@ -43,6 +43,7 @@
 extern const base::Feature kNTPLaunchAfterInactivity;
 extern const base::Feature kNTPOfflinePagesFeature;
 extern const base::Feature NTPShowGoogleGInOmniboxFeature;
+extern const base::Feature kPayWithGoogleV1;
 extern const base::Feature kPhysicalWebFeature;
 extern const base::Feature kPhysicalWebSharing;
 extern const base::Feature kSpecialLocaleFeature;
diff --git a/chrome/browser/android/vr_shell/color_scheme.cc b/chrome/browser/android/vr_shell/color_scheme.cc
index b9a2e9f6..ec78f6b 100644
--- a/chrome/browser/android/vr_shell/color_scheme.cc
+++ b/chrome/browser/android/vr_shell/color_scheme.cc
@@ -74,6 +74,14 @@
   fullscreen_scheme.element_background = 0xCC2B3E48;
   fullscreen_scheme.element_background_hover = 0xCC536B77;
   fullscreen_scheme.element_background_down = 0xCC96AFBB;
+  fullscreen_scheme.close_button_foreground =
+      fullscreen_scheme.element_foreground;
+  fullscreen_scheme.close_button_background =
+      fullscreen_scheme.element_background;
+  fullscreen_scheme.close_button_background_hover =
+      fullscreen_scheme.element_background_hover;
+  fullscreen_scheme.close_button_background_down =
+      fullscreen_scheme.element_background_down;
 
   ColorScheme& incognito_scheme = kColorSchemes[ColorScheme::kModeIncognito];
   incognito_scheme.world_background = 0xFF2E2E2E;
@@ -84,6 +92,14 @@
   incognito_scheme.element_background = 0xCC454545;
   incognito_scheme.element_background_hover = 0xCC505050;
   incognito_scheme.element_background_down = 0xCC888888;
+  incognito_scheme.close_button_foreground =
+      fullscreen_scheme.element_foreground;
+  incognito_scheme.close_button_background =
+      fullscreen_scheme.element_background;
+  incognito_scheme.close_button_background_hover =
+      fullscreen_scheme.element_background_hover;
+  incognito_scheme.close_button_background_down =
+      fullscreen_scheme.element_background_down;
   incognito_scheme.loading_indicator_foreground = 0xFF8A8A8A;
   incognito_scheme.loading_indicator_background = 0xFF454545;
   incognito_scheme.separator = 0xFF474747;
diff --git a/chrome/browser/android/vr_shell/gltf_parser_unittest.cc b/chrome/browser/android/vr_shell/gltf_parser_unittest.cc
index 2e6c1e1..657bcd34 100644
--- a/chrome/browser/android/vr_shell/gltf_parser_unittest.cc
+++ b/chrome/browser/android/vr_shell/gltf_parser_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/memory/ptr_util.h"
-#include "base/path_service.h"
 #include "base/values.h"
 #include "chrome/browser/android/vr_shell/test/paths.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -19,9 +18,7 @@
 
 class DataDrivenTest : public testing::Test {
  protected:
-  static void SetUpTestCase() { test::RegisterPathProvider(); }
-
-  void SetUp() override { PathService::Get(test::DIR_TEST_DATA, &data_dir_); }
+  void SetUp() override { test::GetTestDataPath(&data_dir_); }
 
   base::FilePath data_dir_;
 };
diff --git a/chrome/browser/android/vr_shell/test/paths.cc b/chrome/browser/android/vr_shell/test/paths.cc
index eb8d941..b06cabd 100644
--- a/chrome/browser/android/vr_shell/test/paths.cc
+++ b/chrome/browser/android/vr_shell/test/paths.cc
@@ -4,44 +4,24 @@
 
 #include "chrome/browser/android/vr_shell/test/paths.h"
 
-#include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 namespace vr_shell {
 namespace test {
 
-namespace {
-
-bool PathProvider(int key, base::FilePath* result) {
-  base::FilePath cur;
-  switch (key) {
-    // The following are only valid in the development environment, and
-    // will fail if executed from an installed executable (because the
-    // generated path won't exist).
-    case DIR_TEST_DATA:
-      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
-        return false;
-      cur = cur.Append(FILE_PATH_LITERAL("chrome"))
-                .Append(FILE_PATH_LITERAL("browser"))
-                .Append(FILE_PATH_LITERAL("android"))
-                .Append(FILE_PATH_LITERAL("vr_shell"))
-                .Append(FILE_PATH_LITERAL("test"))
-                .Append(FILE_PATH_LITERAL("data"));
-      if (!base::PathExists(cur))
-        return false;
-      break;
-    default:
-      return false;
-  }
-  *result = cur;
-  return true;
-}
-
-}  // namespace
-
-void RegisterPathProvider() {
-  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
+void GetTestDataPath(base::FilePath* result) {
+  base::FilePath path;
+  ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &path));
+  path = path.Append(FILE_PATH_LITERAL("chrome"))
+             .Append(FILE_PATH_LITERAL("browser"))
+             .Append(FILE_PATH_LITERAL("android"))
+             .Append(FILE_PATH_LITERAL("vr_shell"))
+             .Append(FILE_PATH_LITERAL("test"))
+             .Append(FILE_PATH_LITERAL("data"));
+  ASSERT_TRUE(base::PathExists(path));
+  *result = path;
 }
 
 }  // namespace test
diff --git a/chrome/browser/android/vr_shell/test/paths.h b/chrome/browser/android/vr_shell/test/paths.h
index fb66dba5..6c358c7 100644
--- a/chrome/browser/android/vr_shell/test/paths.h
+++ b/chrome/browser/android/vr_shell/test/paths.h
@@ -5,19 +5,12 @@
 #ifndef CHROME_BROWSER_ANDROID_VR_SHELL_TEST_PATHS_H_
 #define CHROME_BROWSER_ANDROID_VR_SHELL_TEST_PATHS_H_
 
+#include "base/files/file_path.h"
+
 namespace vr_shell {
 namespace test {
 
-enum {
-  PATH_START = 12000,
-
-  // Valid only in testing environments.
-  DIR_TEST_DATA,
-  PATH_END,
-};
-
-// Call once to register the provider for the path keys defined above.
-void RegisterPathProvider();
+void GetTestDataPath(base::FilePath* result);
 
 }  // namespace test
 }  // namespace vr_shell
diff --git a/chrome/browser/android/vr_shell/textures/close_button_texture.cc b/chrome/browser/android/vr_shell/textures/close_button_texture.cc
index 7de21dcf..7b57e21 100644
--- a/chrome/browser/android/vr_shell/textures/close_button_texture.cc
+++ b/chrome/browser/android/vr_shell/textures/close_button_texture.cc
@@ -38,9 +38,9 @@
   size_.set_width(texture_size.width());
 
   cc::PaintFlags flags;
-  SkColor color = hovered() ? color_scheme().element_background_hover
-                            : color_scheme().element_background;
-  color = pressed() ? color_scheme().element_background_down : color;
+  SkColor color = hovered() ? color_scheme().close_button_background_hover
+                            : color_scheme().close_button_background;
+  color = pressed() ? color_scheme().close_button_background_down : color;
   flags.setColor(color);
   canvas->DrawCircle(gfx::PointF(size_.width() / 2, size_.height() / 2),
                      size_.width() / 2, flags);
@@ -49,7 +49,7 @@
   canvas->Translate(gfx::Vector2d(size_.height() * (1 - kIconScaleFactor) / 2,
                                   size_.height() * (1 - kIconScaleFactor) / 2));
   PaintVectorIcon(canvas, ui::kCloseIcon, size_.height() * kIconScaleFactor,
-                  color_scheme().element_foreground);
+                  color_scheme().close_button_foreground);
   canvas->Restore();
 }
 
diff --git a/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc b/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc
index a7e7b726..acbbec0 100644
--- a/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc
+++ b/chrome/browser/android/vr_shell/textures/url_bar_texture_unittest.cc
@@ -127,11 +127,14 @@
   MockRenderText mock_;
 };
 
+#if !defined(OS_LINUX)
+// TODO(crbug/731894): This test does not work on Linux.
 TEST(UrlBarTextureTest, WillNotFailOnNonAsciiURLs) {
   TestUrlBarTexture texture;
   EXPECT_EQ(3lu, texture.GetNumberOfFontFallbacksForURL(
                      GURL("http://中央大学.ಠ_ಠ.tw/")));
 }
+#endif
 
 TEST_F(UrlEmphasisTest, SecureHttpsHost) {
   EXPECT_CALL(mock_, SetColor(kDeemphasizedColor));
diff --git a/chrome/browser/chromeos/enrollment_dialog_view.cc b/chrome/browser/chromeos/enrollment_dialog_view.cc
index 0964b48..75d6357 100644
--- a/chrome/browser/chromeos/enrollment_dialog_view.cc
+++ b/chrome/browser/chromeos/enrollment_dialog_view.cc
@@ -189,7 +189,8 @@
   grid_layout->StartRow(0, 0);
   grid_layout->AddView(label);
   grid_layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+      0,
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
   grid_layout->Layout(this);
 }
 
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
index 3939fc4..0364a12c 100644
--- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
+++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -232,7 +232,7 @@
     // Wait for the session merge to finish.
     WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE);
 
-    // Check for existance of refresh token.
+    // Check for existence of refresh token.
     ProfileOAuth2TokenService* token_service =
           ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
     EXPECT_TRUE(token_service->RefreshTokenIsAvailable(account_id));
@@ -459,7 +459,7 @@
 // PRE_MergeSession is testing merge session for a new profile.
 IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_PRE_PRE_MergeSession) {
   StartNewUserSession(true);
-  // Check for existance of refresh token.
+  // Check for existence of refresh token.
   std::string account_id = PickAccountId(profile(), kTestGaiaId, kTestEmail);
   ProfileOAuth2TokenService* token_service =
         ProfileOAuth2TokenServiceFactory::GetForProfile(
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index fb8514f1..56cecaa 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -50,6 +50,10 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/app_modal/javascript_app_modal_dialog.h"
 #include "components/app_modal/native_app_modal_dialog.h"
+#include "components/autofill/content/browser/content_autofill_driver.h"
+#include "components/autofill/content/browser/content_autofill_driver_factory.h"
+#include "components/autofill/core/browser/autofill_manager.h"
+#include "components/autofill/core/browser/autofill_manager_test_delegate.h"
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/content_browser_client.h"
@@ -129,6 +133,8 @@
     "files/workers/debug_shared_worker_initialization.js";
 const char kEmulateNetworkConditionsPage[] =
     "files/devtools/emulate_network_conditions.html";
+const char kDispatchKeyEventShowsAutoFill[] =
+    "files/devtools/dispatch_key_event_shows_auto_fill.html";
 
 template <typename... T>
 void DispatchOnTestSuiteSkipCheck(DevToolsWindow* window,
@@ -1696,6 +1702,47 @@
   RunTest("testDispatchKeyEventDoesNotCrash", "about:blank");
 }
 
+class AutofillManagerTestDelegateDevtoolsImpl
+    : public autofill::AutofillManagerTestDelegate {
+ public:
+  explicit AutofillManagerTestDelegateDevtoolsImpl(
+      WebContents* inspectedContents)
+      : inspected_contents_(inspectedContents) {}
+  ~AutofillManagerTestDelegateDevtoolsImpl() override {}
+
+  void DidPreviewFormData() override {}
+
+  void DidFillFormData() override {}
+
+  void DidShowSuggestions() override {
+    ASSERT_TRUE(content::ExecuteScript(inspected_contents_,
+                                       "console.log('didShowSuggestions');"));
+  }
+
+  void OnTextFieldChanged() override {}
+
+ private:
+  WebContents* inspected_contents_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateDevtoolsImpl);
+};
+
+IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestDispatchKeyEventShowsAutoFill) {
+  OpenDevToolsWindow(kDispatchKeyEventShowsAutoFill, false);
+
+  autofill::ContentAutofillDriver* autofill_driver =
+      autofill::ContentAutofillDriverFactory::FromWebContents(GetInspectedTab())
+          ->DriverForFrame(GetInspectedTab()->GetMainFrame());
+  autofill::AutofillManager* autofill_manager =
+      autofill_driver->autofill_manager();
+  AutofillManagerTestDelegateDevtoolsImpl autoFillTestDelegate(
+      GetInspectedTab());
+  autofill_manager->SetTestDelegate(&autoFillTestDelegate);
+
+  RunTestFunction(window_, "testDispatchKeyEventShowsAutoFill");
+  CloseDevToolsWindow();
+}
+
 // Tests that settings are stored in profile correctly.
 IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestSettings) {
   OpenDevToolsWindow("about:blank", true);
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
index 220ccf1..bbc87a00 100644
--- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
+++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -149,8 +149,8 @@
     // Create a screens list.
     if (show_screens) {
 #if defined(USE_ASH)
-      screen_list =
-          base::MakeUnique<DesktopMediaListAsh>(DesktopMediaListAsh::SCREENS);
+      screen_list = base::MakeUnique<DesktopMediaListAsh>(
+          content::DesktopMediaID::TYPE_SCREEN);
 #else   // !defined(USE_ASH)
       screen_list = base::MakeUnique<NativeDesktopMediaList>(
           content::DesktopMediaID::TYPE_SCREEN,
@@ -161,8 +161,8 @@
     // Create a windows list.
     if (show_windows) {
 #if defined(USE_ASH)
-      window_list =
-          base::MakeUnique<DesktopMediaListAsh>(DesktopMediaListAsh::WINDOWS);
+      window_list = base::MakeUnique<DesktopMediaListAsh>(
+          content::DesktopMediaID::TYPE_WINDOW);
 #else   // !defined(USE_ASH)
       window_list = base::MakeUnique<NativeDesktopMediaList>(
           content::DesktopMediaID::TYPE_WINDOW,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 848906f..1795663 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1377,13 +1377,6 @@
     "Improved translate target language and triggering logic by considering "
     "information from User Language Profile (ULP).";
 
-const char kViewsRectBasedTargetingName[] = "Rect-based targeting in views";
-
-const char kViewsRectBasedTargetingDescription[] =
-    "Rect-based targeting uses a heuristic to determine the most probable "
-    "target of a gesture, where the touch region is represented by a "
-    "rectangle.";
-
 const char kPermissionActionReportingName[] = "Permission Action Reporting";
 
 const char kPermissionActionReportingDescription[] =
@@ -1527,6 +1520,12 @@
 
 #if defined(OS_ANDROID)
 
+extern const char kPayWithGoogleV1Name[] = "Pay with Google v1";
+
+extern const char kPayWithGoogleV1Description[] =
+    "Enable Pay with Google integration into Web Payments with API version "
+    "'1'.";
+
 const char kProgressBarAnimationName[] =
     "Android phone page loading progress bar animation";
 
@@ -2305,8 +2304,7 @@
 const char kEnableTouchSupportForScreenMagnifierDescription[] =
     "Enables touch support for screen magnifier";
 
-const char kEnableZipArchiverOnFileManagerName[] =
-    "ZIP archiver for Drive";
+const char kEnableZipArchiverOnFileManagerName[] = "ZIP archiver for Drive";
 
 const char kEnableZipArchiverOnFileManagerDescription[] =
     "Enable the ability to archive and unpack files on Drive in the Files app";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 42e9f39..2f170e239 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -764,9 +764,6 @@
 extern const char kVideoRotateToFullscreenName[];
 extern const char kVideoRotateToFullscreenDescription[];
 
-extern const char kViewsRectBasedTargetingName[];
-extern const char kViewsRectBasedTargetingDescription[];
-
 extern const char kWalletServiceUseSandboxName[];
 extern const char kWalletServiceUseSandboxDescription[];
 
@@ -1054,6 +1051,9 @@
 extern const char kOffliningRecentPagesName[];
 extern const char kOffliningRecentPagesDescription[];
 
+extern const char kPayWithGoogleV1Name[];
+extern const char kPayWithGoogleV1Description[];
+
 extern const char kProgressBarAnimationName[];
 extern const char kProgressBarAnimationDescription[];
 extern const char kProgressBarAnimationLinear[];
diff --git a/chrome/browser/media/webrtc/desktop_media_list_ash.cc b/chrome/browser/media/webrtc/desktop_media_list_ash.cc
index b03d108..6b262e9 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_ash.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_ash.cc
@@ -15,6 +15,7 @@
 #include "ui/snapshot/snapshot.h"
 
 using content::BrowserThread;
+using content::DesktopMediaID;
 
 namespace {
 
@@ -23,12 +24,15 @@
 
 }  // namespace
 
-DesktopMediaListAsh::DesktopMediaListAsh(int source_types)
+DesktopMediaListAsh::DesktopMediaListAsh(content::DesktopMediaID::Type type)
     : DesktopMediaListBase(
           base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)),
-      source_types_(source_types),
+      type_(type),
       pending_window_capture_requests_(0),
-      weak_factory_(this) {}
+      weak_factory_(this) {
+  DCHECK(type == content::DesktopMediaID::TYPE_SCREEN ||
+         type == content::DesktopMediaID::TYPE_WINDOW);
+}
 
 DesktopMediaListAsh::~DesktopMediaListAsh() {}
 
@@ -70,7 +74,7 @@
   aura::Window::Windows root_windows = ash::Shell::GetAllRootWindows();
 
   for (size_t i = 0; i < root_windows.size(); ++i) {
-    if (source_types_ & SCREENS) {
+    if (type_ == content::DesktopMediaID::TYPE_SCREEN) {
       SourceDescription screen_source(
           content::DesktopMediaID::RegisterAuraWindow(
               content::DesktopMediaID::TYPE_SCREEN, root_windows[i]),
@@ -98,9 +102,7 @@
       }
 
       CaptureThumbnail(screen_source.id, root_windows[i]);
-    }
-
-    if (source_types_ & WINDOWS) {
+    } else {
       EnumerateWindowsForRoot(
           sources, root_windows[i], ash::kShellWindowId_DefaultContainer);
       EnumerateWindowsForRoot(
diff --git a/chrome/browser/media/webrtc/desktop_media_list_ash.h b/chrome/browser/media/webrtc/desktop_media_list_ash.h
index 8cdd2871..3e5b8e17 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_ash.h
+++ b/chrome/browser/media/webrtc/desktop_media_list_ash.h
@@ -21,12 +21,7 @@
 // native windows.
 class DesktopMediaListAsh : public DesktopMediaListBase {
  public:
-  enum SourceTypes {
-    SCREENS = 1,
-    WINDOWS = 2,
-  };
-
-  explicit DesktopMediaListAsh(int source_types);
+  explicit DesktopMediaListAsh(content::DesktopMediaID::Type type);
   ~DesktopMediaListAsh() override;
 
  private:
@@ -42,7 +37,7 @@
   void OnThumbnailCaptured(content::DesktopMediaID id,
                            const gfx::Image& image);
 
-  int source_types_;
+  const content::DesktopMediaID::Type type_;
 
   int pending_window_capture_requests_;
 
diff --git a/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc b/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
index c8db1f8..b5b0956c 100644
--- a/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
+++ b/chrome/browser/media/webrtc/desktop_media_list_ash_unittest.cc
@@ -44,8 +44,8 @@
     ash::test::AshTestBase::TearDown();
   }
 
-  void CreateList(int source_types) {
-    list_.reset(new DesktopMediaListAsh(source_types));
+  void CreateList(content::DesktopMediaID::Type type) {
+    list_.reset(new DesktopMediaListAsh(type));
     list_->SetThumbnailSize(gfx::Size(kThumbnailSize, kThumbnailSize));
 
     // Set update period to reduce the time it takes to run tests.
@@ -63,40 +63,8 @@
       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
 }
 
-TEST_F(DesktopMediaListAshTest, Screen) {
-  CreateList(DesktopMediaListAsh::SCREENS | DesktopMediaListAsh::WINDOWS);
-
-  EXPECT_CALL(observer_, OnSourceAdded(list_.get(), 0));
-  EXPECT_CALL(observer_, OnSourceThumbnailChanged(list_.get(), 0))
-      .WillOnce(QuitMessageLoop())
-      .WillRepeatedly(DoDefault());
-  list_->StartUpdating(&observer_);
-  base::RunLoop().Run();
-}
-
-TEST_F(DesktopMediaListAshTest, OneWindow) {
-  CreateList(DesktopMediaListAsh::SCREENS | DesktopMediaListAsh::WINDOWS);
-
-  std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
-
-  EXPECT_CALL(observer_, OnSourceAdded(list_.get(), 0));
-  EXPECT_CALL(observer_, OnSourceAdded(list_.get(), 1));
-  EXPECT_CALL(observer_, OnSourceThumbnailChanged(list_.get(), 0))
-      .Times(AtLeast(1));
-  EXPECT_CALL(observer_, OnSourceThumbnailChanged(list_.get(), 1))
-      .WillOnce(QuitMessageLoop())
-      .WillRepeatedly(DoDefault());
-  EXPECT_CALL(observer_, OnSourceRemoved(list_.get(), 1))
-      .WillOnce(QuitMessageLoop());
-
-  list_->StartUpdating(&observer_);
-  base::RunLoop().Run();
-  window.reset();
-  base::RunLoop().Run();
-}
-
 TEST_F(DesktopMediaListAshTest, ScreenOnly) {
-  CreateList(DesktopMediaListAsh::SCREENS);
+  CreateList(content::DesktopMediaID::TYPE_SCREEN);
 
   std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
 
@@ -110,7 +78,7 @@
 }
 
 TEST_F(DesktopMediaListAshTest, WindowOnly) {
-  CreateList(DesktopMediaListAsh::WINDOWS);
+  CreateList(content::DesktopMediaID::TYPE_WINDOW);
 
   std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0));
 
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index 9d24cd6d..699bee1e 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -177,6 +177,7 @@
     bool metrics_reporting_enabled,
     const base::FilePath& dir,
     base::StringPiece metrics_name,
+    metrics::FileMetricsProvider::SourceAssociation association,
     scoped_refptr<base::TaskRunner> task_runner,
     metrics::FileMetricsProvider* file_metrics_provider) {
   base::FilePath metrics_file;
@@ -188,7 +189,7 @@
     file_metrics_provider->RegisterSource(
         metrics_file,
         metrics::FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
-        metrics::FileMetricsProvider::ASSOCIATE_PREVIOUS_RUN, metrics_name);
+        association, metrics_name);
   } else {
     // When metrics reporting is not enabled, any existing file should be
     // deleted in order to preserve user privacy.
@@ -223,7 +224,8 @@
         metrics_reporting_enabled && (send_unreported == "yes");
     RegisterOrRemovePreviousRunMetricsFile(
         report_previous_persistent_histograms, user_data_dir,
-        ChromeMetricsServiceClient::kBrowserMetricsName, task_runner,
+        ChromeMetricsServiceClient::kBrowserMetricsName,
+        metrics::FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, task_runner,
         file_metrics_provider.get());
 
     // Register the Crashpad metrics files.
@@ -231,8 +233,10 @@
     // cleanly.
     RegisterOrRemovePreviousRunMetricsFile(
         metrics_reporting_enabled, user_data_dir,
-        kCrashpadHistogramAllocatorName, task_runner,
-        file_metrics_provider.get());
+        kCrashpadHistogramAllocatorName,
+        metrics::FileMetricsProvider::
+            ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN,
+        task_runner, file_metrics_provider.get());
     if (metrics_reporting_enabled) {
       base::FilePath active_path;
       base::GlobalHistogramAllocator::ConstructFilePaths(
diff --git a/chrome/browser/pdf/pdf_extension_util.cc b/chrome/browser/pdf/pdf_extension_util.cc
index 774bdcf..3290c51f 100644
--- a/chrome/browser/pdf/pdf_extension_util.cc
+++ b/chrome/browser/pdf/pdf_extension_util.cc
@@ -32,7 +32,8 @@
           IDR_PDF_MANIFEST).as_string();
   DCHECK(manifest_contents.find(kNameTag) != std::string::npos);
   base::ReplaceFirstSubstringAfterOffset(
-      &manifest_contents, 0, kNameTag, ChromeContentClient::kPDFPluginName);
+      &manifest_contents, 0, kNameTag,
+      ChromeContentClient::kPDFExtensionPluginName);
 
   return manifest_contents;
 }
diff --git a/chrome/browser/plugins/plugin_policy_handler.cc b/chrome/browser/plugins/plugin_policy_handler.cc
index a6eca4e..05c637c2 100644
--- a/chrome/browser/plugins/plugin_policy_handler.cc
+++ b/chrome/browser/plugins/plugin_policy_handler.cc
@@ -53,7 +53,10 @@
     std::string plugin;
     if (!plugins->GetString(i, &plugin))
       continue;
-    if (base::MatchPattern(ChromeContentClient::kPDFPluginName, plugin) &&
+    if ((base::MatchPattern(ChromeContentClient::kPDFExtensionPluginName,
+                            plugin) ||
+         base::MatchPattern(ChromeContentClient::kPDFInternalPluginName,
+                            plugin)) &&
         !policies.GetValue(policy::key::kAlwaysOpenPdfExternally)) {
       prefs->SetValue(prefs::kPluginsAlwaysOpenPdfExternally,
                       base::MakeUnique<base::Value>(disable_pdf_plugin));
@@ -104,7 +107,10 @@
     std::string plugin;
     if (!plugins->GetString(i, &plugin))
       continue;
-    if (base::MatchPattern(ChromeContentClient::kPDFPluginName, plugin) &&
+    if ((base::MatchPattern(ChromeContentClient::kPDFExtensionPluginName,
+                            plugin) ||
+         base::MatchPattern(ChromeContentClient::kPDFInternalPluginName,
+                            plugin)) &&
         !policies.GetValue(policy::key::kAlwaysOpenPdfExternally)) {
       prefs->RemoveValue(prefs::kPluginsAlwaysOpenPdfExternally);
     }
diff --git a/chrome/browser/plugins/plugin_prefs.cc b/chrome/browser/plugins/plugin_prefs.cc
index 4dcae31..b08000e 100644
--- a/chrome/browser/plugins/plugin_prefs.cc
+++ b/chrome/browser/plugins/plugin_prefs.cc
@@ -49,7 +49,10 @@
 namespace {
 
 bool IsPDFViewerPlugin(const base::string16& plugin_name) {
-  return plugin_name == base::ASCIIToUTF16(ChromeContentClient::kPDFPluginName);
+  return (plugin_name ==
+          base::ASCIIToUTF16(ChromeContentClient::kPDFExtensionPluginName)) ||
+         (plugin_name ==
+          base::ASCIIToUTF16(ChromeContentClient::kPDFInternalPluginName));
 }
 
 bool IsAdobeFlashPlayerPlugin(const base::string16& plugin_name) {
diff --git a/chrome/browser/plugins/plugin_prefs_unittest.cc b/chrome/browser/plugins/plugin_prefs_unittest.cc
index 16b6ce8..b116943 100644
--- a/chrome/browser/plugins/plugin_prefs_unittest.cc
+++ b/chrome/browser/plugins/plugin_prefs_unittest.cc
@@ -24,12 +24,12 @@
 
 TEST_F(PluginPrefsTest, AlwaysOpenPdfExternally) {
   EXPECT_EQ(PluginPrefs::NO_POLICY,
-            plugin_prefs_->PolicyStatusForPlugin(
-                base::ASCIIToUTF16(ChromeContentClient::kPDFPluginName)));
+            plugin_prefs_->PolicyStatusForPlugin(base::ASCIIToUTF16(
+                ChromeContentClient::kPDFExtensionPluginName)));
 
   SetAlwaysOpenPdfExternally(true);
 
   EXPECT_EQ(PluginPrefs::POLICY_DISABLED,
-            plugin_prefs_->PolicyStatusForPlugin(
-                base::ASCIIToUTF16(ChromeContentClient::kPDFPluginName)));
+            plugin_prefs_->PolicyStatusForPlugin(base::ASCIIToUTF16(
+                ChromeContentClient::kPDFExtensionPluginName)));
 }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 3e4a0ec..27d85bf 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1201,6 +1201,7 @@
       "//chrome/common:features",
       "//components/feedback/proto",
       "//components/proximity_auth/webui",
+      "//components/ui_metrics",
       "//components/web_modal",
       "//components/zoom",
       "//device/bluetooth",
diff --git a/chrome/browser/ui/DEPS b/chrome/browser/ui/DEPS
index 7f89d23..effbf2bed 100644
--- a/chrome/browser/ui/DEPS
+++ b/chrome/browser/ui/DEPS
@@ -5,6 +5,7 @@
   "+components/favicon/core",
   "+components/flags_ui",
   "+components/toolbar",
+  "+components/ui_metrics",
   "+components/url_formatter",
   "+components/version_ui",
   "+components/webapks_ui",
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
index 797ca910..53ce50b 100644
--- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
+++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
@@ -6,6 +6,7 @@
 
 #include <cmath>
 
+#include "base/feature_list.h"
 #include "base/mac/mac_util.h"
 #import "base/mac/sdk_forward_declarations.h"
 #include "base/stl_util.h"
@@ -18,6 +19,7 @@
 #include "components/omnibox/browser/autocomplete_match.h"
 #include "components/omnibox/browser/autocomplete_match_type.h"
 #include "components/omnibox/browser/omnibox_edit_model.h"
+#include "components/omnibox/browser/omnibox_field_trial.h"
 #include "components/omnibox/browser/omnibox_popup_model.h"
 #include "components/toolbar/vector_icons.h"
 #include "skia/ext/skia_utils_mac.h"
@@ -216,12 +218,28 @@
 
   // Calculate the popup's position on the screen.
   NSRect popup_frame = anchor_rect_base;
+
+  bool match_omnibox_width =
+      base::FeatureList::IsEnabled(omnibox::kUIExperimentNarrowDropdown);
+
+  CGFloat table_width = match_omnibox_width
+                            ? NSWidth([field_ bounds])
+                            : NSWidth([[[field_ window] contentView] bounds]);
+  DCHECK_GT(table_width, 0.0);
+
+  NSPoint field_origin_base =
+      [field_ convertPoint:[field_ bounds].origin toView:nil];
+
   // Size to fit the matrix and shift down by the size.
   popup_frame.size.height = matrixHeight + PopupPaddingVertical() * 2.0;
   popup_frame.size.height += [OmniboxPopupTopSeparatorView preferredHeight];
   popup_frame.size.height += [OmniboxPopupBottomSeparatorView preferredHeight];
+  popup_frame.origin.x = match_omnibox_width ? field_origin_base.x : 0;
   popup_frame.origin.y -= NSHeight(popup_frame);
 
+  if (match_omnibox_width)
+    popup_frame.size.width = table_width;
+
   // Shift to screen coordinates.
   if ([controller window]) {
     popup_frame = [[controller window] convertRectToScreen:popup_frame];
@@ -251,18 +269,10 @@
   background_rect.origin.y = NSMaxY(top_separator_frame);
   [background_view_ setFrame:background_rect];
 
-  // In Material Design, the table is the width of the window. In non-MD,
-  // calculate the width of the table based on backing out the popup's border
-  // from the width of the field.
-  CGFloat table_width = NSWidth([[[field_ window] contentView] bounds]);
-  DCHECK_GT(table_width, 0.0);
-
   // Matrix.
-  NSPoint field_origin_base =
-      [field_ convertPoint:[field_ bounds].origin toView:nil];
   NSRect matrix_frame = NSZeroRect;
   matrix_frame.origin.x = 0;
-  [matrix_ setContentLeftPadding:field_origin_base.x];
+  [matrix_ setContentLeftPadding:match_omnibox_width ? 0 : field_origin_base.x];
   matrix_frame.origin.y = PopupPaddingVertical();
   matrix_frame.size.width = table_width;
   matrix_frame.size.height = matrixHeight;
diff --git a/chrome/browser/ui/sad_tab.cc b/chrome/browser/ui/sad_tab.cc
index 2a9d3b9..8fb280c6 100644
--- a/chrome/browser/ui/sad_tab.cc
+++ b/chrome/browser/ui/sad_tab.cc
@@ -16,6 +16,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/feedback/feedback_util.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/ui_metrics/sadtab_metrics_types.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -39,23 +40,13 @@
     UMA_HISTOGRAM_COUNTS_1000(histogram_name, count); \
   }
 
-// This enum backs an UMA histogram, so it should be treated as append-only.
-// A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.tab
-enum SadTabEvent {
-  DISPLAYED,
-  BUTTON_CLICKED,
-  HELP_LINK_CLICKED,
-  MAX_SAD_TAB_EVENT
-};
-
-void RecordEvent(bool feedback, SadTabEvent event) {
+void RecordEvent(bool feedback, ui_metrics::SadTabEvent event) {
   if (feedback) {
-    UMA_HISTOGRAM_ENUMERATION("Tabs.SadTab.Feedback.Event", event,
-                              SadTabEvent::MAX_SAD_TAB_EVENT);
+    UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabFeedbackHistogramKey, event,
+                              ui_metrics::SadTabEvent::MAX_SAD_TAB_EVENT);
   } else {
-    UMA_HISTOGRAM_ENUMERATION("Tabs.SadTab.Reload.Event", event,
-                              SadTabEvent::MAX_SAD_TAB_EVENT);
+    UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabReloadHistogramKey, event,
+                              ui_metrics::SadTabEvent::MAX_SAD_TAB_EVENT);
   }
 }
 
@@ -224,14 +215,15 @@
       break;
   }
 
-  RecordEvent(show_feedback_button_, SadTabEvent::DISPLAYED);
+  RecordEvent(show_feedback_button_, ui_metrics::SadTabEvent::DISPLAYED);
 }
 
 void SadTab::PerformAction(SadTab::Action action) {
   DCHECK(recorded_paint_);
   switch (action) {
     case Action::BUTTON:
-      RecordEvent(show_feedback_button_, SadTabEvent::BUTTON_CLICKED);
+      RecordEvent(show_feedback_button_,
+                  ui_metrics::SadTabEvent::BUTTON_CLICKED);
       if (show_feedback_button_) {
         ShowFeedbackPage(
             FindBrowserWithWebContents(web_contents_),
@@ -246,7 +238,8 @@
       }
       break;
     case Action::HELP_LINK:
-      RecordEvent(show_feedback_button_, SadTabEvent::HELP_LINK_CLICKED);
+      RecordEvent(show_feedback_button_,
+                  ui_metrics::SadTabEvent::HELP_LINK_CLICKED);
       content::OpenURLParams params(GURL(GetHelpLinkURL()), content::Referrer(),
                                     WindowOpenDisposition::CURRENT_TAB,
                                     ui::PAGE_TRANSITION_LINK, false);
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
index 04e98e4..f2dbaef 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_dialog_views.cc
@@ -138,7 +138,7 @@
   dialog_body_contents->SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kVertical,
       provider->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS),
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL)));
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
   dialog_body_contents->AddChildView(new AppInfoSummaryPanel(profile, app));
   dialog_body_contents->AddChildView(new AppInfoPermissionsPanel(profile, app));
 
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
index 1287efa..51895e0 100644
--- a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
@@ -254,7 +254,7 @@
 
   views::View* vertical_stack =
       CreateVerticalStack(ChromeLayoutProvider::Get()->GetDistanceMetric(
-          DISTANCE_UNRELATED_CONTROL_VERTICAL));
+          views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
   AddChildView(vertical_stack);
 
   AddDescriptionAndLinksControl(vertical_stack);
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
index 6ca27d4..c418d39a 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -191,7 +191,7 @@
 
   view->SetLayoutManager(new views::BoxLayout(
       views::BoxLayout::kVertical, gfx::Insets(),
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL)));
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL)));
 
   // Add the card type icon, last four digits and expiration date.
   views::View* description_view = new views::View();
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index 1ec7339..1f9e404 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -389,7 +389,7 @@
   GridLayout* layout = GridLayout::CreatePanel(pane);
   int unrelated_vertical_distance =
       ChromeLayoutProvider::Get()->GetDistanceMetric(
-          DISTANCE_UNRELATED_CONTROL_VERTICAL);
+          views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
 
   const int single_column_layout_id = 0;
   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
@@ -453,7 +453,7 @@
   GridLayout* layout = GridLayout::CreatePanel(pane);
   int unrelated_vertical_distance =
       ChromeLayoutProvider::Get()->GetDistanceMetric(
-          DISTANCE_UNRELATED_CONTROL_VERTICAL);
+          views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
 
   const int single_column_layout_id = 0;
   views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc
index e27d209..e66e5d1 100644
--- a/chrome/browser/ui/views/content_setting_bubble_contents.cc
+++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -213,7 +213,7 @@
   const int related_control_vertical_spacing =
       provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL);
   const int unrelated_control_vertical_spacing =
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL);
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
 
   const int kSingleColumnSetId = 0;
   views::ColumnSet* column_set = layout->AddColumnSet(kSingleColumnSetId);
diff --git a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
index 736c541..256c7ea 100644
--- a/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
+++ b/chrome/browser/ui/views/crypto_module_password_dialog_view.cc
@@ -144,8 +144,8 @@
 
   layout->StartRow(0, 0);
   layout->AddView(reason_label_);
-  layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+  layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   layout->StartRow(0, 1);
   layout->AddView(password_label_);
diff --git a/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc b/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc
index 0dbee7b..bbc2ab6 100644
--- a/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc
+++ b/chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bubble_view.cc
@@ -74,8 +74,8 @@
   promotion_text_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   layout->StartRow(0, kLabelColumnSet);
   layout->AddView(promotion_text_label_);
-  layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+  layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
   layout->StartRow(0, kDoubleButtonColumnSet);
   layout->AddView(send_sms_button_);
   layout->AddView(no_button_);
diff --git a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
index e20b62f8..93dcf5b 100644
--- a/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
+++ b/chrome/browser/ui/views/extensions/chooser_dialog_view.cc
@@ -78,8 +78,8 @@
       new views::DialogClientView(widget, GetContentsView());
   ChromeLayoutProvider* provider = ChromeLayoutProvider::Get();
   client->SetButtonRowInsets(gfx::Insets(
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL), 0, 0,
-      0));
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL),
+      0, 0, 0));
   return client;
 }
 
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc
index 2498801..a66a6b4aa 100644
--- a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc
+++ b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc
@@ -29,7 +29,7 @@
     case DISTANCE_BUTTON_MINIMUM_WIDTH:
       return views::kMinimumButtonWidth;
     case DISTANCE_CONTROL_LIST_VERTICAL:
-      return GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL);
+      return GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
     case DISTANCE_DIALOG_BUTTON_TOP:
       return 0;
     case DISTANCE_RELATED_CONTROL_HORIZONTAL_SMALL:
@@ -44,8 +44,6 @@
       return views::kUnrelatedControlHorizontalSpacing;
     case DISTANCE_UNRELATED_CONTROL_HORIZONTAL_LARGE:
       return views::kUnrelatedControlLargeHorizontalSpacing;
-    case DISTANCE_UNRELATED_CONTROL_VERTICAL:
-      return views::kUnrelatedControlVerticalSpacing;
     case DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE:
       return views::kUnrelatedControlLargeVerticalSpacing;
     default:
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.h b/chrome/browser/ui/views/harmony/chrome_layout_provider.h
index dd264ee..318cab5 100644
--- a/chrome/browser/ui/views/harmony/chrome_layout_provider.h
+++ b/chrome/browser/ui/views/harmony/chrome_layout_provider.h
@@ -34,8 +34,6 @@
   DISTANCE_UNRELATED_CONTROL_HORIZONTAL,
   // Larger horizontal spacing between unrelated controls.
   DISTANCE_UNRELATED_CONTROL_HORIZONTAL_LARGE,
-  // Vertical spacing between controls that are logically unrelated.
-  DISTANCE_UNRELATED_CONTROL_VERTICAL,
   // Larger vertical spacing between unrelated controls.
   DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE,
 };
diff --git a/chrome/browser/ui/views/harmony/harmony_layout_provider.cc b/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
index fd1c37a..365023c 100644
--- a/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
+++ b/chrome/browser/ui/views/harmony/harmony_layout_provider.cc
@@ -61,7 +61,7 @@
       return kHarmonyLayoutUnit;
     case DISTANCE_UNRELATED_CONTROL_HORIZONTAL_LARGE:
       return kHarmonyLayoutUnit;
-    case DISTANCE_UNRELATED_CONTROL_VERTICAL:
+    case views::DISTANCE_UNRELATED_CONTROL_VERTICAL:
       return kHarmonyLayoutUnit;
     case DISTANCE_UNRELATED_CONTROL_VERTICAL_LARGE:
       return kHarmonyLayoutUnit;
diff --git a/chrome/browser/ui/views/login_view.cc b/chrome/browser/ui/views/login_view.cc
index f77b16a..6fdea248 100644
--- a/chrome/browser/ui/views/login_view.cc
+++ b/chrome/browser/ui/views/login_view.cc
@@ -93,8 +93,8 @@
   layout->AddView(password_field_);
 
   if (provider->UseExtraDialogPadding()) {
-    layout->AddPaddingRow(
-        0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+    layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                                 views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
   }
 
   if (login_model_data) {
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
index f68f6d6..ecb3c0f 100644
--- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -1508,7 +1508,7 @@
   bool is_primary_account = primary_account == account_id_to_remove_;
 
   const int unrelated_vertical_spacing =
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL);
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
 
   // Adds main text.
   layout->StartRowWithPadding(1, 0, 0, unrelated_vertical_spacing);
@@ -1575,7 +1575,7 @@
   columns->AddPaddingColumn(0, dialog_insets.right());
 
   const int unrelated_vertical_spacing =
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL);
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
 
   // Adds main text.
   layout->StartRowWithPadding(1, 1, 0, unrelated_vertical_spacing);
diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc
index c62972d..6821744 100644
--- a/chrome/browser/ui/views/sad_tab_view.cc
+++ b/chrome/browser/ui/views/sad_tab_view.cc
@@ -43,7 +43,7 @@
   label->SetMultiLine(true);
   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   label->SetLineHeight(ChromeLayoutProvider::Get()->GetDistanceMetric(
-      DISTANCE_UNRELATED_CONTROL_VERTICAL));
+      views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
   return label;
 }
 
@@ -143,7 +143,7 @@
                   views::GridLayout::LEADING);
 
   layout->AddPaddingRow(2, provider->GetDistanceMetric(
-      DISTANCE_UNRELATED_CONTROL_VERTICAL));
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   views::Widget::InitParams sad_tab_params(
       views::Widget::InitParams::TYPE_CONTROL);
diff --git a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
index 83d1476..9e486f8 100644
--- a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
+++ b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
@@ -34,7 +34,7 @@
   views::MessageBoxView::InitParams init_params(delegate->GetDialogMessage());
   init_params.inter_row_vertical_spacing =
       ChromeLayoutProvider::Get()->GetDistanceMetric(
-          DISTANCE_UNRELATED_CONTROL_VERTICAL);
+          views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
   message_box_view_ = new views::MessageBoxView(init_params);
 
   base::string16 link_text(delegate->GetLinkText());
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index ac62eaa..ca399dfc 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -627,7 +627,7 @@
   }
 
   layout->AddPaddingRow(0, provider->GetDistanceMetric(
-      DISTANCE_UNRELATED_CONTROL_VERTICAL));
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   layout->StartRow(0, COLUMN_SET_ID_CONTENT);
   views::LabelButton* accept_button =
@@ -706,8 +706,8 @@
     AddIconToLayout(layout);
   layout->AddView(label);
 
-  layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+  layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   layout->StartRow(0, COLUMN_SET_ID_CONTENT);
   views::LabelButton* revert_button =
@@ -759,8 +759,8 @@
   layout->AddView(
       CreateLink(this, IDS_TRANSLATE_BUBBLE_ADVANCED, LINK_ID_ADVANCED));
 
-  layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+  layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   layout->StartRow(0, COLUMN_SET_ID_CONTENT);
   views::LabelButton* button = views::MdTextButton::CreateSecondaryUiButton(
@@ -810,8 +810,8 @@
   layout->AddView(
       CreateLink(this, IDS_TRANSLATE_BUBBLE_ADVANCED, LINK_ID_ADVANCED));
 
-  layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+  layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   layout->StartRow(0, COLUMN_SET_ID_CONTENT);
   views::LabelButton* button = views::MdTextButton::CreateSecondaryUiButton(
@@ -909,8 +909,8 @@
     layout->AddView(advanced_always_translate_checkbox_);
   }
 
-  layout->AddPaddingRow(
-      0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL));
+  layout->AddPaddingRow(0, provider->GetDistanceMetric(
+                               views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
   layout->StartRow(0, COLUMN_SET_ID_BUTTONS);
   // TODO(estade): this should use CreateExtraView().
diff --git a/chrome/browser/ui/views/try_chrome_dialog_view.cc b/chrome/browser/ui/views/try_chrome_dialog_view.cc
index ae5022f9..c410bb9 100644
--- a/chrome/browser/ui/views/try_chrome_dialog_view.cc
+++ b/chrome/browser/ui/views/try_chrome_dialog_view.cc
@@ -111,7 +111,7 @@
   const int unrelated_space_horiz =
       provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL);
   const int unrelated_space_vert =
-      provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_VERTICAL);
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
   const int button_spacing_horiz =
       provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL);
 
diff --git a/chrome/browser/ui/views/uninstall_view.cc b/chrome/browser/ui/views/uninstall_view.cc
index 861776d..5569240 100644
--- a/chrome/browser/ui/views/uninstall_view.cc
+++ b/chrome/browser/ui/views/uninstall_view.cc
@@ -62,8 +62,8 @@
 
   const int checkbox_indent = provider->GetDistanceMetric(
       DISTANCE_SUBSECTION_HORIZONTAL_INDENT);
-  const int unrelated_vertical_spacing = provider->GetDistanceMetric(
-      DISTANCE_UNRELATED_CONTROL_VERTICAL);
+  const int unrelated_vertical_spacing =
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL);
   const int related_vertical_spacing = provider->GetDistanceMetric(
       views::DISTANCE_RELATED_CONTROL_VERTICAL);
   const int related_horizontal_spacing = provider->GetDistanceMetric(
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index b7429b1..5633f322 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -162,7 +162,7 @@
   content::PepperPluginInfo pdf_info;
   pdf_info.is_internal = true;
   pdf_info.is_out_of_process = true;
-  pdf_info.name = ChromeContentClient::kPDFPluginName;
+  pdf_info.name = ChromeContentClient::kPDFInternalPluginName;
   pdf_info.description = kPDFPluginDescription;
   pdf_info.path = base::FilePath::FromUTF8Unsafe(
       ChromeContentClient::kPDFPluginPath);
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h
index e3a0afb7..475adfce 100644
--- a/chrome/common/chrome_content_client.h
+++ b/chrome/common/chrome_content_client.h
@@ -35,7 +35,8 @@
   // on-demand and therefore should still appear in navigator.plugins.
   static const char kNotPresent[];
 #endif
-  static const char kPDFPluginName[];
+  static const char kPDFExtensionPluginName[];
+  static const char kPDFInternalPluginName[];
   static const char kPDFPluginPath[];
   static const char kRemotingViewerPluginPath[];
 
diff --git a/chrome/common/chrome_content_client_constants.cc b/chrome/common/chrome_content_client_constants.cc
index cd0e7bc..bab9707 100644
--- a/chrome/common/chrome_content_client_constants.cc
+++ b/chrome/common/chrome_content_client_constants.cc
@@ -6,9 +6,13 @@
 
 #if defined(GOOGLE_CHROME_BUILD)
 const char ChromeContentClient::kNotPresent[] = "internal-not-yet-present";
-const char ChromeContentClient::kPDFPluginName[] = "Chrome PDF Viewer";
+const char ChromeContentClient::kPDFExtensionPluginName[] = "Chrome PDF Viewer";
+const char ChromeContentClient::kPDFInternalPluginName[] = "Chrome PDF Plugin";
 #else
-const char ChromeContentClient::kPDFPluginName[] = "Chromium PDF Viewer";
+const char ChromeContentClient::kPDFExtensionPluginName[] =
+    "Chromium PDF Viewer";
+const char ChromeContentClient::kPDFInternalPluginName[] =
+    "Chromium PDF Plugin";
 #endif
 const char ChromeContentClient::kPDFPluginPath[] = "internal-pdf-viewer";
 const char ChromeContentClient::kRemotingViewerPluginPath[] =
diff --git a/chrome/installer/util/scoped_user_protocol_entry.h b/chrome/installer/util/scoped_user_protocol_entry.h
index eee58d2..85ad2d9 100644
--- a/chrome/installer/util/scoped_user_protocol_entry.h
+++ b/chrome/installer/util/scoped_user_protocol_entry.h
@@ -15,7 +15,7 @@
 // Windows 8 shows the "No apps are installed to open this type of link"
 // dialog when choosing a default handler for a |protocol| under certain
 // circumstances. Under these circumstances, it appears that ensuring the
-// existance of the HKCU\Software\Classes\<protocol> key with an empty "URL
+// existence of the HKCU\Software\Classes\<protocol> key with an empty "URL
 // Protocol" value is sufficient to make the dialog contain the usual list of
 // registered browsers. This class creates this key and value in its constructor
 // if needed, and cleans them up in its destructor if no other values or subkeys
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 55acb6a..8fa3e7e 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -824,7 +824,8 @@
         // Report PDF load metrics. Since the PDF plugin is comprised of an
         // extension that loads a second plugin, avoid double counting by
         // ignoring the creation of the second plugin.
-        if (info.name == ASCIIToUTF16(ChromeContentClient::kPDFPluginName) &&
+        if (info.name ==
+                ASCIIToUTF16(ChromeContentClient::kPDFExtensionPluginName) &&
             GURL(frame->GetDocument().Url()).host_piece() !=
                 extension_misc::kPdfExtensionId) {
           bool is_main_frame_plugin_document =
@@ -876,7 +877,8 @@
       case ChromeViewHostMsg_GetPluginInfo_Status::kDisabled: {
         PluginUMAReporter::GetInstance()->ReportPluginDisabled(orig_mime_type,
                                                                url);
-        if (info.name == ASCIIToUTF16(ChromeContentClient::kPDFPluginName)) {
+        if (info.name ==
+            ASCIIToUTF16(ChromeContentClient::kPDFExtensionPluginName)) {
           ReportPDFLoadStatus(
               PDFLoadStatus::kShowedDisabledPluginPlaceholderForEmbeddedPdf);
         }
diff --git a/chrome/test/data/devtools/dispatch_key_event_shows_auto_fill.html b/chrome/test/data/devtools/dispatch_key_event_shows_auto_fill.html
new file mode 100644
index 0000000..e418575
--- /dev/null
+++ b/chrome/test/data/devtools/dispatch_key_event_shows_auto_fill.html
@@ -0,0 +1,22 @@
+<html>
+<head>
+<script>
+function run()
+{
+    if (window.location.toString().endsWith("?name=Abbf")) {
+        document.getElementById("name").value = "";
+        document.getElementById("name").focus();
+        console.log("ready");
+        return;
+    }
+    document.getElementById("submit").click();
+}
+</script>
+</head>
+<body onload="run()">
+    <form action="?" onsubmit="this.action += window.location.hash">
+        <input type="text" id="name" name="name" value="Abbf" />
+        <input type="submit" id="submit" value="submit" />
+    </form>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/api_test/native_bindings/extension/background.js b/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
index 516cf9b0..3285345 100644
--- a/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
+++ b/chrome/test/data/extensions/api_test/native_bindings/extension/background.js
@@ -17,19 +17,16 @@
 // methods, etc). If any of these stages failed, the test itself would also
 // fail.
 var tests = [
-  function idleApi() {
-    chrome.test.assertTrue(!!chrome.idle);
-    chrome.test.assertTrue(!!chrome.idle.IdleState);
-    chrome.test.assertTrue(!!chrome.idle.IdleState.IDLE);
-    chrome.test.assertTrue(!!chrome.idle.IdleState.ACTIVE);
-    chrome.test.assertTrue(!!chrome.idle.queryState);
-    chrome.idle.queryState(1000, function(state) {
-      // Depending on the machine, this could come back as either idle or
-      // active. However, all we're curious about is the bindings themselves
-      // (not the API implementation), so as long as it's a possible response,
-      // it's a success for our purposes.
-      chrome.test.assertTrue(state == chrome.idle.IdleState.IDLE ||
-                             state == chrome.idle.IdleState.ACTIVE);
+  function historyApi() {
+    chrome.test.assertTrue(!!chrome.history);
+    chrome.test.assertTrue(!!chrome.history.TransitionType);
+    chrome.test.assertTrue(!!chrome.history.TransitionType.LINK);
+    chrome.test.assertTrue(!!chrome.history.TransitionType.TYPED);
+    chrome.test.assertTrue(!!chrome.history.getVisits);
+    chrome.history.getVisits({url: 'http://example.com'}, function(visits) {
+      // We're just testing the bindings, not the history API, so we don't
+      // care about the response.
+      chrome.test.assertTrue(!!visits);
       chrome.test.succeed();
     });
   },
diff --git a/chrome/test/data/extensions/api_test/native_bindings/extension/manifest.json b/chrome/test/data/extensions/api_test/native_bindings/extension/manifest.json
index d185dd2..62a49ff 100644
--- a/chrome/test/data/extensions/api_test/native_bindings/extension/manifest.json
+++ b/chrome/test/data/extensions/api_test/native_bindings/extension/manifest.json
@@ -4,7 +4,7 @@
   "description": "A simple e2e test for native bindings, id is ddchlicdkolnonkihahngkmmmjnjlkkf",
   "manifest_version": 2,
   "version": "0.1",
-  "permissions": ["idle", "tabs", "cast.streaming", "*://example.com:*/*",
+  "permissions": ["history", "tabs", "cast.streaming", "*://example.com:*/*",
                   "storage", "privacy", "webNavigation", "contentSettings"],
   "background": {
     "persistent": false,
diff --git a/chrome/test/data/webui/i18n_behavior_test.html b/chrome/test/data/webui/i18n_behavior_test.html
index 18eda26..e79ef72 100644
--- a/chrome/test/data/webui/i18n_behavior_test.html
+++ b/chrome/test/data/webui/i18n_behavior_test.html
@@ -7,7 +7,7 @@
 
 var allowedByDefault = '<a href="https://google.com">Google!</a>';
 var text = 'I\'m just text, nobody should have a problem with me!';
-var nonBreakingSpace = 'A\u00a0B';  // 0xa0 is a unicode nbsp.
+var nonBreakingSpace = 'A\u00a0B\u00a0C';  // \u00a0 is a unicode nbsp.
 
 function setUpPage() {
   loadTimeData.data = {
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn
index 48571fb..348b104 100644
--- a/chromecast/browser/android/BUILD.gn
+++ b/chromecast/browser/android/BUILD.gn
@@ -60,6 +60,7 @@
     ":cast_shell_manifest",
     "//base:base_java",
     "//chromecast/base:base_java",
+    "//components/crash/android:java",
     "//content/public/android:content_java",
     "//device/geolocation:geolocation_java",
     "//media/base/android:media_java",
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc
index fbc3612..d6093d4a 100644
--- a/chromeos/network/network_state_handler.cc
+++ b/chromeos/network/network_state_handler.cc
@@ -563,7 +563,7 @@
   tether_network_state->set_battery_percentage(battery_percentage);
   tether_network_state->set_signal_strength(signal_strength);
 
-  NotifyNetworkListChanged();
+  NotifyNetworkPropertiesUpdated(tether_network_state);
   return true;
 }
 
@@ -581,7 +581,8 @@
   }
 
   tether_network_state->set_tether_has_connected_to_host(true);
-  NotifyNetworkListChanged();
+
+  NotifyNetworkPropertiesUpdated(tether_network_state);
   return true;
 }
 
@@ -605,31 +606,37 @@
 
 bool NetworkStateHandler::DisassociateTetherNetworkStateFromWifiNetwork(
     const std::string& tether_network_guid) {
-  NetworkState* tether_network =
+  NetworkState* tether_network_state =
       GetModifiableNetworkStateFromGuid(tether_network_guid);
 
-  if (!tether_network) {
+  if (!tether_network_state) {
     NET_LOG(ERROR) << "DisassociateTetherNetworkStateWithWifiNetwork(): Tether "
                    << "network with ID " << tether_network_guid
                    << " not registered; could not remove association.";
     return false;
   }
 
-  std::string wifi_network_guid = tether_network->tether_guid();
-  NetworkState* wifi_network =
+  std::string wifi_network_guid = tether_network_state->tether_guid();
+  NetworkState* wifi_network_state =
       GetModifiableNetworkStateFromGuid(wifi_network_guid);
 
-  if (!wifi_network) {
+  if (!wifi_network_state) {
     NET_LOG(ERROR) << "DisassociateTetherNetworkStateWithWifiNetwork(): Wi-Fi "
                    << "network with ID " << wifi_network_guid
                    << " not registered; could not remove association.";
     return false;
   }
 
-  wifi_network->set_tether_guid(std::string());
-  tether_network->set_tether_guid(std::string());
+  if (wifi_network_state->tether_guid().empty() &&
+      tether_network_state->tether_guid().empty()) {
+    return true;
+  }
 
-  NotifyNetworkListChanged();
+  wifi_network_state->set_tether_guid(std::string());
+  tether_network_state->set_tether_guid(std::string());
+
+  NotifyNetworkPropertiesUpdated(wifi_network_state);
+  NotifyNetworkPropertiesUpdated(tether_network_state);
 
   return true;
 }
@@ -644,46 +651,52 @@
     return false;
   }
 
-  NetworkState* tether_network =
+  NetworkState* tether_network_state =
       GetModifiableNetworkStateFromGuid(tether_network_guid);
-  if (!tether_network) {
+  if (!tether_network_state) {
     NET_LOG(ERROR) << "Tether network does not exist: " << tether_network_guid;
     return false;
   }
-  if (!NetworkTypePattern::Tether().MatchesType(tether_network->type())) {
+  if (!NetworkTypePattern::Tether().MatchesType(tether_network_state->type())) {
     NET_LOG(ERROR) << "Network is not a Tether network: "
                    << tether_network_guid;
     return false;
   }
 
-  NetworkState* wifi_network =
+  NetworkState* wifi_network_state =
       GetModifiableNetworkStateFromGuid(wifi_network_guid);
-  if (!wifi_network) {
+  if (!wifi_network_state) {
     NET_LOG(ERROR) << "Wi-Fi Network does not exist: " << wifi_network_guid;
     return false;
   }
-  if (!NetworkTypePattern::WiFi().MatchesType(wifi_network->type())) {
+  if (!NetworkTypePattern::WiFi().MatchesType(wifi_network_state->type())) {
     NET_LOG(ERROR) << "Network is not a W-Fi network: " << wifi_network_guid;
     return false;
   }
 
-  tether_network->set_tether_guid(wifi_network_guid);
-  wifi_network->set_tether_guid(tether_network_guid);
-  NotifyNetworkListChanged();
+  if (wifi_network_state->tether_guid() == tether_network_guid &&
+      tether_network_state->tether_guid() == wifi_network_guid) {
+    return true;
+  }
+
+  tether_network_state->set_tether_guid(wifi_network_guid);
+  wifi_network_state->set_tether_guid(tether_network_guid);
+
+  NotifyNetworkPropertiesUpdated(wifi_network_state);
+  NotifyNetworkPropertiesUpdated(tether_network_state);
+
   return true;
 }
 
 void NetworkStateHandler::SetTetherNetworkStateDisconnected(
     const std::string& guid) {
-  // TODO(khorimoto): Remove the Tether network as the default network, and
-  // send a connection status change.
+  // TODO(khorimoto): Remove the Tether network as the default network.
   SetTetherNetworkStateConnectionState(guid, shill::kStateDisconnect);
 }
 
 void NetworkStateHandler::SetTetherNetworkStateConnecting(
     const std::string& guid) {
-  // TODO(khorimoto): Set the Tether network as the default network, and send
-  // a connection status change.
+  // TODO(khorimoto): Set the Tether network as the default network.
   SetTetherNetworkStateConnectionState(guid, shill::kStateConfiguration);
 }
 
@@ -694,24 +707,35 @@
   DCHECK(GetNetworkStateFromGuid(GetNetworkStateFromGuid(guid)->tether_guid())
              ->tether_guid() == guid);
 
-  // TODO(khorimoto): Send a connection status change.
   SetTetherNetworkStateConnectionState(guid, shill::kStateOnline);
 }
 
 void NetworkStateHandler::SetTetherNetworkStateConnectionState(
     const std::string& guid,
     const std::string& connection_state) {
-  NetworkState* tether_network = GetModifiableNetworkStateFromGuid(guid);
-  if (!tether_network) {
+  NetworkState* tether_network_state = GetModifiableNetworkStateFromGuid(guid);
+  if (!tether_network_state) {
     NET_LOG(ERROR) << "SetTetherNetworkStateConnectionState: Tether network "
                    << "not found: " << guid;
     return;
   }
 
-  DCHECK(NetworkTypePattern::Tether().MatchesType(tether_network->type()));
+  DCHECK(
+      NetworkTypePattern::Tether().MatchesType(tether_network_state->type()));
 
-  tether_network->set_connection_state(connection_state);
-  NotifyNetworkListChanged();
+  std::string prev_connection_state = tether_network_state->connection_state();
+  tether_network_state->set_connection_state(connection_state);
+  DCHECK(!tether_network_state->is_captive_portal());
+
+  if (ConnectionStateChanged(tether_network_state, prev_connection_state,
+                             false /* prev_is_captive_portal */)) {
+    NET_LOG(EVENT) << "Changing connection state for Tether network with GUID "
+                   << guid << ". Old state: " << prev_connection_state << ", "
+                   << "New state: " << connection_state;
+
+    OnNetworkConnectionStateChanged(tether_network_state);
+    NotifyNetworkPropertiesUpdated(tether_network_state);
+  }
 }
 
 void NetworkStateHandler::EnsureTetherDeviceState() {
diff --git a/chromeos/network/network_state_handler_unittest.cc b/chromeos/network/network_state_handler_unittest.cc
index ee62d71..ad8af8e 100644
--- a/chromeos/network/network_state_handler_unittest.cc
+++ b/chromeos/network/network_state_handler_unittest.cc
@@ -721,12 +721,14 @@
       NetworkStateHandler::TECHNOLOGY_ENABLED);
 
   EXPECT_EQ(0u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 
   network_state_handler_->AddTetherNetworkState(
       kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
       kTetherSignalStrength1, false /* has_connected_to_network */);
 
   EXPECT_EQ(1u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 
   const NetworkState* tether_network =
       network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
@@ -743,7 +745,8 @@
       kTetherGuid1, "NewCarrier", 5 /* battery_percentage */,
       10 /* signal_strength */));
 
-  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 
   tether_network =
       network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
@@ -759,18 +762,21 @@
   EXPECT_TRUE(
       network_state_handler_->SetTetherNetworkHasConnectedToHost(kTetherGuid1));
 
-  EXPECT_EQ(3u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 
   // Try calling that function again. It should return false and should not
   // trigger a NetworkListChanged() callback for observers.
   EXPECT_FALSE(
       network_state_handler_->SetTetherNetworkHasConnectedToHost(kTetherGuid1));
 
-  EXPECT_EQ(3u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 
   network_state_handler_->RemoveTetherNetworkState(kTetherGuid1);
 
-  EXPECT_EQ(4u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 
   ASSERT_FALSE(network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1));
 
@@ -784,8 +790,6 @@
   network_state_handler_->SetTetherTechnologyState(
       NetworkStateHandler::TECHNOLOGY_ENABLED);
 
-  EXPECT_EQ(0u, test_observer_->network_list_changed_count());
-
   const std::string profile = "/profile/profile1";
   const std::string wifi_path = "/service/wifi_with_guid";
   AddService(wifi_path, kWifiGuid1, kWifiName1, shill::kTypeWifi,
@@ -793,20 +797,27 @@
   profile_test_->AddProfile(profile, "" /* userhash */);
   EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
   UpdateManagerProperties();
+  test_observer_->reset_updates();
 
   EXPECT_EQ(1u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));
 
   network_state_handler_->AddTetherNetworkState(
       kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
       kTetherSignalStrength1, kTetherHasConnectedToHost1);
 
   EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));
 
   EXPECT_TRUE(
       network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
           kTetherGuid1, kWifiGuid1));
 
-  EXPECT_EQ(3u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));
 
   const NetworkState* wifi_network =
       network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
@@ -816,12 +827,28 @@
       network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
   EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());
 
+  // Try associating again. The function call should return true since the
+  // association was successful, but no new observer updates should occur since
+  // no changes happened.
+  EXPECT_TRUE(
+      network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
+          kTetherGuid1, kWifiGuid1));
+
+  EXPECT_EQ(kTetherGuid1, wifi_network->tether_guid());
+  EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());
+
+  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));
+
   network_state_handler_->RemoveTetherNetworkState(kTetherGuid1);
 
-  EXPECT_EQ(4u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(3u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));
 
   wifi_network = network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
-  ASSERT_TRUE(wifi_network->tether_guid().empty());
+  EXPECT_TRUE(wifi_network->tether_guid().empty());
 }
 
 TEST_F(NetworkStateHandlerTest, TetherNetworkStateDisassociation) {
@@ -835,20 +862,27 @@
   profile_test_->AddProfile(profile, "" /* userhash */);
   EXPECT_TRUE(profile_test_->AddService(profile, wifi_path));
   UpdateManagerProperties();
+  test_observer_->reset_updates();
 
   EXPECT_EQ(1u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));
 
   network_state_handler_->AddTetherNetworkState(
       kTetherGuid1, kTetherName1, kTetherCarrier1, kTetherBatteryPercentage1,
       kTetherSignalStrength1, kTetherHasConnectedToHost1);
 
   EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(0, test_observer_->PropertyUpdatesForService(wifi_path));
 
   EXPECT_TRUE(
       network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
           kTetherGuid1, kWifiGuid1));
 
-  EXPECT_EQ(3u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(wifi_path));
 
   const NetworkState* wifi_network =
       network_state_handler_->GetNetworkStateFromGuid(kWifiGuid1);
@@ -858,13 +892,16 @@
       network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
   EXPECT_EQ(kWifiGuid1, tether_network->tether_guid());
 
-  network_state_handler_->DisassociateTetherNetworkStateFromWifiNetwork(
-      kTetherGuid1);
+  EXPECT_TRUE(
+      network_state_handler_->DisassociateTetherNetworkStateFromWifiNetwork(
+          kTetherGuid1));
 
-  ASSERT_TRUE(wifi_network->tether_guid().empty());
-  ASSERT_TRUE(tether_network->tether_guid().empty());
+  EXPECT_TRUE(wifi_network->tether_guid().empty());
+  EXPECT_TRUE(tether_network->tether_guid().empty());
 
-  EXPECT_EQ(4u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2u, test_observer_->network_list_changed_count());
+  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(wifi_path));
 }
 
 TEST_F(NetworkStateHandlerTest, TetherNetworkStateAssociationWifiRemoved) {
@@ -953,6 +990,9 @@
   network_state_handler_->AssociateTetherNetworkStateWithWifiNetwork(
       kTetherGuid1, kWifiGuid1);
 
+  EXPECT_EQ(0, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
+  EXPECT_EQ(1, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+
   const NetworkState* tether_network =
       network_state_handler_->GetNetworkStateFromGuid(kTetherGuid1);
 
@@ -962,15 +1002,27 @@
   network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
   EXPECT_TRUE(tether_network->IsConnectingState());
 
+  EXPECT_EQ(1, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
+  EXPECT_EQ(2, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+
   network_state_handler_->SetTetherNetworkStateConnected(kTetherGuid1);
   EXPECT_TRUE(tether_network->IsConnectedState());
 
+  EXPECT_EQ(2, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
+  EXPECT_EQ(3, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+
   network_state_handler_->SetTetherNetworkStateConnecting(kTetherGuid1);
   EXPECT_TRUE(tether_network->IsReconnecting());
 
+  EXPECT_EQ(3, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
+  EXPECT_EQ(4, test_observer_->PropertyUpdatesForService(kTetherGuid1));
+
   network_state_handler_->SetTetherNetworkStateDisconnected(kTetherGuid1);
   EXPECT_FALSE(tether_network->IsConnectingState());
   EXPECT_FALSE(tether_network->IsConnectedState());
+
+  EXPECT_EQ(4, test_observer_->ConnectionStateChangesForService(kTetherGuid1));
+  EXPECT_EQ(5, test_observer_->PropertyUpdatesForService(kTetherGuid1));
 }
 
 TEST_F(NetworkStateHandlerTest, NetworkConnectionStateChanged) {
diff --git a/chromeos/system/statistics_provider.h b/chromeos/system/statistics_provider.h
index f8c44fb..7f8b3c23 100644
--- a/chromeos/system/statistics_provider.h
+++ b/chromeos/system/statistics_provider.h
@@ -98,7 +98,7 @@
       bool load_oem_manifest) = 0;
 
   // Returns true if the named machine statistic (e.g. "hardware_class") is
-  // found and stores it in |result| (if provided). Probing for the existance of
+  // found and stores it in |result| (if provided). Probing for the existence of
   // a statistic by setting |result| to nullptr supresses the usual warning in
   // case the statistic is not found. Safe to call from any thread except the
   // task runner passed to Initialize() (e.g. FILE). This may block if called
diff --git a/components/feature_engagement_tracker/internal/availability_model_impl.cc b/components/feature_engagement_tracker/internal/availability_model_impl.cc
index fb00d84..994a9bfa 100644
--- a/components/feature_engagement_tracker/internal/availability_model_impl.cc
+++ b/components/feature_engagement_tracker/internal/availability_model_impl.cc
@@ -37,7 +37,7 @@
 
 base::Optional<uint32_t> AvailabilityModelImpl::GetAvailability(
     const base::Feature& feature) const {
-  auto search = feature_availabilities_.find(&feature);
+  auto search = feature_availabilities_.find(feature.name);
   if (search == feature_availabilities_.end())
     return base::nullopt;
 
@@ -47,8 +47,7 @@
 void AvailabilityModelImpl::OnStoreLoadComplete(
     OnInitializedCallback on_initialized_callback,
     bool success,
-    std::unique_ptr<std::map<const base::Feature*, uint32_t>>
-        feature_availabilities) {
+    std::unique_ptr<std::map<std::string, uint32_t>> feature_availabilities) {
   if (!success) {
     std::move(on_initialized_callback).Run(false);
     return;
diff --git a/components/feature_engagement_tracker/internal/availability_model_impl.h b/components/feature_engagement_tracker/internal/availability_model_impl.h
index f32b12f0..a94d63c 100644
--- a/components/feature_engagement_tracker/internal/availability_model_impl.h
+++ b/components/feature_engagement_tracker/internal/availability_model_impl.h
@@ -9,6 +9,7 @@
 
 #include <map>
 #include <memory>
+#include <string>
 
 #include "base/callback.h"
 #include "base/macros.h"
@@ -45,12 +46,12 @@
   void OnStoreLoadComplete(
       OnInitializedCallback on_initialized_callback,
       bool success,
-      std::unique_ptr<std::map<const base::Feature*, uint32_t>>
-          feature_availabilities);
+      std::unique_ptr<std::map<std::string, uint32_t>> feature_availabilities);
 
   // Stores the day number since epoch (1970-01-01) in the local timezone for
-  // when the particular |feature| was made available.
-  std::map<const base::Feature*, uint32_t> feature_availabilities_;
+  // when the particular feature was made available. The key is the feature
+  // name.
+  std::map<std::string, uint32_t> feature_availabilities_;
 
   // Whether the model has successfully initialied.
   bool ready_;
diff --git a/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc b/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc
index 490955c..37c3672e 100644
--- a/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc
+++ b/components/feature_engagement_tracker/internal/availability_model_impl_unittest.cc
@@ -41,7 +41,7 @@
   // SetUpModel exists so that the filter can be changed for any test.
   void SetUpModel(
       bool success,
-      std::unique_ptr<std::map<const base::Feature*, uint32_t>> store_content) {
+      std::unique_ptr<std::map<std::string, uint32_t>> store_content) {
     auto store_loader = base::BindOnce(&AvailabilityModelImplTest::StoreLoader,
                                        base::Unretained(this), success,
                                        std::move(store_content));
@@ -53,7 +53,7 @@
 
   void StoreLoader(
       bool success,
-      std::unique_ptr<std::map<const base::Feature*, uint32_t>> store_content,
+      std::unique_ptr<std::map<std::string, uint32_t>> store_content,
       AvailabilityStore::OnLoadedCallback callback,
       uint32_t current_day) {
     current_day_ = current_day;
@@ -74,8 +74,7 @@
 }  // namespace
 
 TEST_F(AvailabilityModelImplTest, InitializationSuccess) {
-  SetUpModel(true,
-             base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+  SetUpModel(true, base::MakeUnique<std::map<std::string, uint32_t>>());
   EXPECT_FALSE(availability_model_->IsReady());
   availability_model_->Initialize(std::move(initialized_callback_), 14u);
   EXPECT_TRUE(availability_model_->IsReady());
@@ -85,8 +84,7 @@
 }
 
 TEST_F(AvailabilityModelImplTest, InitializationFailed) {
-  SetUpModel(false,
-             base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+  SetUpModel(false, base::MakeUnique<std::map<std::string, uint32_t>>());
   EXPECT_FALSE(availability_model_->IsReady());
   availability_model_->Initialize(std::move(initialized_callback_), 14u);
   EXPECT_FALSE(availability_model_->IsReady());
@@ -96,11 +94,10 @@
 }
 
 TEST_F(AvailabilityModelImplTest, SuccessfullyLoadThreeFeatures) {
-  auto availabilities =
-      base::MakeUnique<std::map<const base::Feature*, uint32_t>>();
-  availabilities->insert(std::make_pair(&kTestFeatureFoo, 100u));
-  availabilities->insert(std::make_pair(&kTestFeatureBar, 200u));
-  availabilities->insert(std::make_pair(&kTestFeatureNop, 300u));
+  auto availabilities = base::MakeUnique<std::map<std::string, uint32_t>>();
+  availabilities->insert(std::make_pair(kTestFeatureFoo.name, 100u));
+  availabilities->insert(std::make_pair(kTestFeatureBar.name, 200u));
+  availabilities->insert(std::make_pair(kTestFeatureNop.name, 300u));
 
   SetUpModel(true, std::move(availabilities));
   availability_model_->Initialize(std::move(initialized_callback_), 14u);
@@ -114,11 +111,10 @@
 }
 
 TEST_F(AvailabilityModelImplTest, FailToLoadThreeFeatures) {
-  auto availabilities =
-      base::MakeUnique<std::map<const base::Feature*, uint32_t>>();
-  availabilities->insert(std::make_pair(&kTestFeatureFoo, 100u));
-  availabilities->insert(std::make_pair(&kTestFeatureBar, 200u));
-  availabilities->insert(std::make_pair(&kTestFeatureNop, 300u));
+  auto availabilities = base::MakeUnique<std::map<std::string, uint32_t>>();
+  availabilities->insert(std::make_pair(kTestFeatureFoo.name, 100u));
+  availabilities->insert(std::make_pair(kTestFeatureBar.name, 200u));
+  availabilities->insert(std::make_pair(kTestFeatureNop.name, 300u));
 
   SetUpModel(false, std::move(availabilities));
   availability_model_->Initialize(std::move(initialized_callback_), 14u);
diff --git a/components/feature_engagement_tracker/internal/availability_store.cc b/components/feature_engagement_tracker/internal/availability_store.cc
index 8877818..55de2bf 100644
--- a/components/feature_engagement_tracker/internal/availability_store.cc
+++ b/components/feature_engagement_tracker/internal/availability_store.cc
@@ -32,8 +32,7 @@
 void OnDBUpdateComplete(
     std::unique_ptr<leveldb_proto::ProtoDatabase<Availability>> db,
     AvailabilityStore::OnLoadedCallback on_loaded_callback,
-    std::unique_ptr<std::map<const base::Feature*, uint32_t>>
-        feature_availabilities,
+    std::unique_ptr<std::map<std::string, uint32_t>> feature_availabilities,
     bool success) {
   stats::RecordDbUpdate(success, stats::StoreType::AVAILABILITY_STORE);
   std::move(on_loaded_callback).Run(success, std::move(feature_availabilities));
@@ -49,8 +48,7 @@
   stats::RecordAvailabilityDbLoadEvent(success);
   if (!success) {
     std::move(on_loaded_callback)
-        .Run(false,
-             base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+        .Run(false, base::MakeUnique<std::map<std::string, uint32_t>>());
     return;
   }
 
@@ -63,7 +61,7 @@
 
   // Find all availabilities from DB and find out what should be deleted.
   auto feature_availabilities =
-      base::MakeUnique<std::map<const base::Feature*, uint32_t>>();
+      base::MakeUnique<std::map<std::string, uint32_t>>();
   auto deletes = base::MakeUnique<std::vector<std::string>>();
   for (auto& availability : *availabilities) {
     // Check if in |feature_filter|.
@@ -81,14 +79,16 @@
     }
 
     // Both in |feature_filter| and is enabled, so keep around.
-    feature_availabilities->insert(std::make_pair(feature, availability.day()));
+    feature_availabilities->insert(
+        std::make_pair(feature->name, availability.day()));
   }
 
   // Find features from |feature_filter| that are enabled, but not in DB yet.
   auto additions = base::MakeUnique<KeyAvailabilityList>();
   for (const base::Feature* feature : feature_filter) {
     // Check if already in DB.
-    if (feature_availabilities->find(feature) != feature_availabilities->end())
+    if (feature_availabilities->find(feature->name) !=
+        feature_availabilities->end())
       continue;
 
     // Check if enabled.
@@ -103,7 +103,8 @@
         std::make_pair(availability.feature_name(), std::move(availability)));
 
     // Since it will be written to the DB, also add to the callback result.
-    feature_availabilities->insert(std::make_pair(feature, availability.day()));
+    feature_availabilities->insert(
+        std::make_pair(feature->name, availability.day()));
   }
 
   // Write all changes to the DB.
@@ -124,8 +125,7 @@
 
   if (!success) {
     std::move(on_loaded_callback)
-        .Run(false,
-             base::MakeUnique<std::map<const base::Feature*, uint32_t>>());
+        .Run(false, base::MakeUnique<std::map<std::string, uint32_t>>());
     return;
   }
 
diff --git a/components/feature_engagement_tracker/internal/availability_store.h b/components/feature_engagement_tracker/internal/availability_store.h
index 891b07c..9326940f 100644
--- a/components/feature_engagement_tracker/internal/availability_store.h
+++ b/components/feature_engagement_tracker/internal/availability_store.h
@@ -17,7 +17,6 @@
 #include "components/leveldb_proto/proto_database.h"
 
 namespace base {
-struct Feature;
 class FilePath;
 }  // namespace base
 
@@ -32,9 +31,8 @@
   // empty. The value for each entry in the map is the day number since epoch
   // (1970-01-01) in the local timezone for when the particular feature was made
   // available.
-  using OnLoadedCallback = base::OnceCallback<void(
-      bool success,
-      std::unique_ptr<std::map<const base::Feature*, uint32_t>>)>;
+  using OnLoadedCallback = base::OnceCallback<
+      void(bool success, std::unique_ptr<std::map<std::string, uint32_t>>)>;
 
   // Loads the availability data, updates the DB with newly enabled features,
   // deletes features that are not enabled anymore, and asynchronously invokes
diff --git a/components/feature_engagement_tracker/internal/availability_store_unittest.cc b/components/feature_engagement_tracker/internal/availability_store_unittest.cc
index a62a1374..cfa4a58 100644
--- a/components/feature_engagement_tracker/internal/availability_store_unittest.cc
+++ b/components/feature_engagement_tracker/internal/availability_store_unittest.cc
@@ -62,9 +62,9 @@
     return db;
   }
 
-  void LoadCallback(bool success,
-                    std::unique_ptr<std::map<const base::Feature*, uint32_t>>
-                        availabilities) {
+  void LoadCallback(
+      bool success,
+      std::unique_ptr<std::map<std::string, uint32_t>> availabilities) {
     load_successful_ = success;
     load_results_ = std::move(availabilities);
   }
@@ -77,7 +77,7 @@
 
   // Callback results.
   base::Optional<bool> load_successful_;
-  std::unique_ptr<std::map<const base::Feature*, uint32_t>> load_results_;
+  std::unique_ptr<std::map<std::string, uint32_t>> load_results_;
 
   // |db_availabilities_| is used during creation of the FakeDB in CreateDB(),
   // to simplify what the DB has stored.
@@ -198,14 +198,16 @@
   ASSERT_EQ(2u, load_results_->size());
   ASSERT_EQ(2u, db_availabilities_.size());
 
-  ASSERT_TRUE(load_results_->find(&kTestFeatureFoo) != load_results_->end());
-  EXPECT_EQ(14u, (*load_results_)[&kTestFeatureFoo]);
+  ASSERT_TRUE(load_results_->find(kTestFeatureFoo.name) !=
+              load_results_->end());
+  EXPECT_EQ(14u, (*load_results_)[kTestFeatureFoo.name]);
   ASSERT_TRUE(db_availabilities_.find(kTestFeatureFoo.name) !=
               db_availabilities_.end());
   EXPECT_EQ(14u, db_availabilities_[kTestFeatureFoo.name].day());
 
-  ASSERT_TRUE(load_results_->find(&kTestFeatureBar) != load_results_->end());
-  EXPECT_EQ(14u, (*load_results_)[&kTestFeatureBar]);
+  ASSERT_TRUE(load_results_->find(kTestFeatureBar.name) !=
+              load_results_->end());
+  EXPECT_EQ(14u, (*load_results_)[kTestFeatureBar.name]);
   ASSERT_TRUE(db_availabilities_.find(kTestFeatureBar.name) !=
               db_availabilities_.end());
   EXPECT_EQ(14u, db_availabilities_[kTestFeatureBar.name].day());
@@ -242,14 +244,16 @@
   ASSERT_EQ(2u, load_results_->size());
   ASSERT_EQ(2u, db_availabilities_.size());
 
-  ASSERT_TRUE(load_results_->find(&kTestFeatureFoo) != load_results_->end());
-  EXPECT_EQ(14u, (*load_results_)[&kTestFeatureFoo]);
+  ASSERT_TRUE(load_results_->find(kTestFeatureFoo.name) !=
+              load_results_->end());
+  EXPECT_EQ(14u, (*load_results_)[kTestFeatureFoo.name]);
   ASSERT_TRUE(db_availabilities_.find(kTestFeatureFoo.name) !=
               db_availabilities_.end());
   EXPECT_EQ(14u, db_availabilities_[kTestFeatureFoo.name].day());
 
-  ASSERT_TRUE(load_results_->find(&kTestFeatureBar) != load_results_->end());
-  EXPECT_EQ(10u, (*load_results_)[&kTestFeatureBar]);
+  ASSERT_TRUE(load_results_->find(kTestFeatureBar.name) !=
+              load_results_->end());
+  EXPECT_EQ(10u, (*load_results_)[kTestFeatureBar.name]);
   ASSERT_TRUE(db_availabilities_.find(kTestFeatureBar.name) !=
               db_availabilities_.end());
   EXPECT_EQ(10u, db_availabilities_[kTestFeatureBar.name].day());
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc b/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
index 90d79b3..a76a23d 100644
--- a/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
+++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration.cc
@@ -203,10 +203,10 @@
 void ChromeVariationsConfiguration::ParseFeatureConfig(
     const base::Feature* feature) {
   DCHECK(feature);
-  DCHECK(configs_.find(feature) == configs_.end());
+  DCHECK(configs_.find(feature->name) == configs_.end());
 
   // Initially all new configurations are considered invalid.
-  FeatureConfig& config = configs_[feature];
+  FeatureConfig& config = configs_[feature->name];
   config.valid = false;
   uint32_t parse_errors = 0;
 
@@ -302,7 +302,14 @@
 
 const FeatureConfig& ChromeVariationsConfiguration::GetFeatureConfig(
     const base::Feature& feature) const {
-  auto it = configs_.find(&feature);
+  auto it = configs_.find(feature.name);
+  DCHECK(it != configs_.end());
+  return it->second;
+}
+
+const FeatureConfig& ChromeVariationsConfiguration::GetFeatureConfigByName(
+    const std::string& feature_name) const {
+  auto it = configs_.find(feature_name);
   DCHECK(it != configs_.end());
   return it->second;
 }
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration.h b/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
index 526e728..b4664a7 100644
--- a/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
+++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration.h
@@ -26,6 +26,8 @@
   // Configuration implementation.
   const FeatureConfig& GetFeatureConfig(
       const base::Feature& feature) const override;
+  const FeatureConfig& GetFeatureConfigByName(
+      const std::string& feature_name) const override;
   const Configuration::ConfigMap& GetRegisteredFeatures() const override;
 
   // Parses the variations configuration for all of the given |features| and
diff --git a/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc b/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
index 9b6e1ea..63f4e922 100644
--- a/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
+++ b/components/feature_engagement_tracker/internal/chrome_variations_configuration_unittest.cc
@@ -44,9 +44,9 @@
         base::FieldTrialList::CreateFieldTrial(kBarTrialName, kGroupName);
     base::FieldTrial* qux_trial =
         base::FieldTrialList::CreateFieldTrial(kQuxTrialName, kGroupName);
-    trials_[&kTestFeatureFoo] = foo_trial;
-    trials_[&kTestFeatureBar] = bar_trial;
-    trials_[&kTestFeatureQux] = qux_trial;
+    trials_[kTestFeatureFoo.name] = foo_trial;
+    trials_[kTestFeatureBar.name] = bar_trial;
+    trials_[kTestFeatureQux.name] = qux_trial;
 
     std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
     feature_list->RegisterFieldTrialOverride(
@@ -73,9 +73,10 @@
  protected:
   void SetFeatureParams(const base::Feature& feature,
                         std::map<std::string, std::string> params) {
-    ASSERT_TRUE(base::FieldTrialParamAssociator::GetInstance()
-                    ->AssociateFieldTrialParams(trials_[&feature]->trial_name(),
-                                                kGroupName, params));
+    ASSERT_TRUE(
+        base::FieldTrialParamAssociator::GetInstance()
+            ->AssociateFieldTrialParams(trials_[feature.name]->trial_name(),
+                                        kGroupName, params));
 
     std::map<std::string, std::string> actualParams;
     EXPECT_TRUE(base::GetFieldTrialParamsByFeature(feature, &actualParams));
@@ -100,7 +101,7 @@
 
  private:
   base::FieldTrialList field_trials_;
-  std::map<const base::Feature*, base::FieldTrial*> trials_;
+  std::map<std::string, base::FieldTrial*> trials_;
   base::test::ScopedFeatureList scoped_feature_list;
 
   DISALLOW_COPY_AND_ASSIGN(ChromeVariationsConfigurationTest);
diff --git a/components/feature_engagement_tracker/internal/configuration.h b/components/feature_engagement_tracker/internal/configuration.h
index c942e5b..8253c4d7 100644
--- a/components/feature_engagement_tracker/internal/configuration.h
+++ b/components/feature_engagement_tracker/internal/configuration.h
@@ -115,7 +115,7 @@
 class Configuration {
  public:
   // Convenience alias for typical implementations of Configuration.
-  using ConfigMap = std::map<const base::Feature*, FeatureConfig>;
+  using ConfigMap = std::map<std::string, FeatureConfig>;
 
   virtual ~Configuration() = default;
 
@@ -124,6 +124,11 @@
   virtual const FeatureConfig& GetFeatureConfig(
       const base::Feature& feature) const = 0;
 
+  // Returns the FeatureConfig for the given |feature|. The |feature_name| must
+  // be registered with the Configuration instance.
+  virtual const FeatureConfig& GetFeatureConfigByName(
+      const std::string& feature_name) const = 0;
+
   // Returns the immutable ConfigMap that contains all registered features.
   virtual const ConfigMap& GetRegisteredFeatures() const = 0;
 
diff --git a/components/feature_engagement_tracker/internal/editable_configuration.cc b/components/feature_engagement_tracker/internal/editable_configuration.cc
index 9559f1ea..6ebbd71 100644
--- a/components/feature_engagement_tracker/internal/editable_configuration.cc
+++ b/components/feature_engagement_tracker/internal/editable_configuration.cc
@@ -6,6 +6,7 @@
 
 #include <map>
 
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "components/feature_engagement_tracker/internal/configuration.h"
 
@@ -18,12 +19,19 @@
 void EditableConfiguration::SetConfiguration(
     const base::Feature* feature,
     const FeatureConfig& feature_config) {
-  configs_[feature] = feature_config;
+  configs_[feature->name] = feature_config;
 }
 
 const FeatureConfig& EditableConfiguration::GetFeatureConfig(
     const base::Feature& feature) const {
-  auto it = configs_.find(&feature);
+  auto it = configs_.find(feature.name);
+  DCHECK(it != configs_.end());
+  return it->second;
+}
+
+const FeatureConfig& EditableConfiguration::GetFeatureConfigByName(
+    const std::string& feature_name) const {
+  auto it = configs_.find(feature_name);
   DCHECK(it != configs_.end());
   return it->second;
 }
diff --git a/components/feature_engagement_tracker/internal/editable_configuration.h b/components/feature_engagement_tracker/internal/editable_configuration.h
index 7d26122..b0168ac 100644
--- a/components/feature_engagement_tracker/internal/editable_configuration.h
+++ b/components/feature_engagement_tracker/internal/editable_configuration.h
@@ -25,6 +25,8 @@
   // Configuration implementation.
   const FeatureConfig& GetFeatureConfig(
       const base::Feature& feature) const override;
+  const FeatureConfig& GetFeatureConfigByName(
+      const std::string& feature_name) const override;
   const Configuration::ConfigMap& GetRegisteredFeatures() const override;
 
   // Adds a new FeatureConfig to the current configurations. If it already
diff --git a/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc b/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc
index 3853f39f..652e845 100644
--- a/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc
+++ b/components/feature_engagement_tracker/internal/feature_config_condition_validator_unittest.cc
@@ -84,7 +84,7 @@
 
   base::Optional<uint32_t> GetAvailability(
       const base::Feature& feature) const override {
-    auto search = availabilities_.find(&feature);
+    auto search = availabilities_.find(feature.name);
     if (search == availabilities_.end())
       return base::nullopt;
 
@@ -93,13 +93,13 @@
 
   void SetAvailability(const base::Feature* feature,
                        base::Optional<uint32_t> availability) {
-    availabilities_[feature] = availability;
+    availabilities_[feature->name] = availability;
   }
 
  private:
   bool ready_;
 
-  std::map<const base::Feature*, base::Optional<uint32_t>> availabilities_;
+  std::map<std::string, base::Optional<uint32_t>> availabilities_;
 
   DISALLOW_COPY_AND_ASSIGN(TestAvailabilityModel);
 };
diff --git a/components/feature_engagement_tracker/internal/once_condition_validator.cc b/components/feature_engagement_tracker/internal/once_condition_validator.cc
index 4451e2c..1ae562a 100644
--- a/components/feature_engagement_tracker/internal/once_condition_validator.cc
+++ b/components/feature_engagement_tracker/internal/once_condition_validator.cc
@@ -9,8 +9,7 @@
 
 namespace feature_engagement_tracker {
 
-OnceConditionValidator::OnceConditionValidator()
-    : currently_showing_feature_(nullptr) {}
+OnceConditionValidator::OnceConditionValidator() = default;
 
 OnceConditionValidator::~OnceConditionValidator() = default;
 
@@ -23,26 +22,26 @@
   ConditionValidator::Result result(true);
   result.event_model_ready_ok = model.IsReady();
 
-  result.currently_showing_ok = currently_showing_feature_ == nullptr;
+  result.currently_showing_ok = currently_showing_feature_.empty();
 
   result.config_ok = config.valid;
 
   result.session_rate_ok =
-      shown_features_.find(&feature) == shown_features_.end();
+      shown_features_.find(feature.name) == shown_features_.end();
 
   return result;
 }
 
 void OnceConditionValidator::NotifyIsShowing(const base::Feature& feature) {
-  DCHECK(currently_showing_feature_ == nullptr);
-  DCHECK(shown_features_.find(&feature) == shown_features_.end());
-  shown_features_.insert(&feature);
-  currently_showing_feature_ = &feature;
+  DCHECK(currently_showing_feature_.empty());
+  DCHECK(shown_features_.find(feature.name) == shown_features_.end());
+  shown_features_.insert(feature.name);
+  currently_showing_feature_ = feature.name;
 }
 
 void OnceConditionValidator::NotifyDismissed(const base::Feature& feature) {
-  DCHECK(&feature == currently_showing_feature_);
-  currently_showing_feature_ = nullptr;
+  DCHECK(feature.name == currently_showing_feature_);
+  currently_showing_feature_.clear();
 }
 
 }  // namespace feature_engagement_tracker
diff --git a/components/feature_engagement_tracker/internal/once_condition_validator.h b/components/feature_engagement_tracker/internal/once_condition_validator.h
index 57ea648..53cca7b 100644
--- a/components/feature_engagement_tracker/internal/once_condition_validator.h
+++ b/components/feature_engagement_tracker/internal/once_condition_validator.h
@@ -49,11 +49,11 @@
 
  private:
   // Contains all features that have met conditions within the current session.
-  std::unordered_set<const base::Feature*> shown_features_;
+  std::unordered_set<std::string> shown_features_;
 
   // Which feature that is currently being shown, or nullptr if nothing is
   // currently showing.
-  const base::Feature* currently_showing_feature_;
+  std::string currently_showing_feature_;
 
   DISALLOW_COPY_AND_ASSIGN(OnceConditionValidator);
 };
diff --git a/components/feature_engagement_tracker/internal/single_invalid_configuration.cc b/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
index 5b82515d..518fd63 100644
--- a/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
+++ b/components/feature_engagement_tracker/internal/single_invalid_configuration.cc
@@ -11,7 +11,7 @@
 SingleInvalidConfiguration::SingleInvalidConfiguration() {
   invalid_feature_config_.valid = false;
   invalid_feature_config_.used.name = "nothing_to_see_here";
-};
+}
 
 SingleInvalidConfiguration::~SingleInvalidConfiguration() = default;
 
@@ -20,6 +20,11 @@
   return invalid_feature_config_;
 }
 
+const FeatureConfig& SingleInvalidConfiguration::GetFeatureConfigByName(
+    const std::string& feature_name) const {
+  return invalid_feature_config_;
+}
+
 const Configuration::ConfigMap&
 SingleInvalidConfiguration::GetRegisteredFeatures() const {
   return configs_;
diff --git a/components/feature_engagement_tracker/internal/single_invalid_configuration.h b/components/feature_engagement_tracker/internal/single_invalid_configuration.h
index dd0ea1ff..1e069be 100644
--- a/components/feature_engagement_tracker/internal/single_invalid_configuration.h
+++ b/components/feature_engagement_tracker/internal/single_invalid_configuration.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_SINGLE_INVALID_CONFIGURATION_H_
 #define COMPONENTS_FEATURE_ENGAGEMENT_TRACKER_INTERNAL_SINGLE_INVALID_CONFIGURATION_H_
 
+#include <string>
 #include <unordered_set>
 
 #include "base/macros.h"
@@ -26,6 +27,8 @@
   // Configuration implementation.
   const FeatureConfig& GetFeatureConfig(
       const base::Feature& feature) const override;
+  const FeatureConfig& GetFeatureConfigByName(
+      const std::string& feature_name) const override;
   const Configuration::ConfigMap& GetRegisteredFeatures() const override;
 
  private:
diff --git a/components/feature_engagement_tracker/internal/stats.cc b/components/feature_engagement_tracker/internal/stats.cc
index a3e3e2c..a424bf4 100644
--- a/components/feature_engagement_tracker/internal/stats.cc
+++ b/components/feature_engagement_tracker/internal/stats.cc
@@ -51,12 +51,12 @@
   const Configuration::ConfigMap& features = config->GetRegisteredFeatures();
   std::string feature_name;
   for (const auto& element : features) {
-    const base::Feature* feature = element.first;
+    const std::string fname = element.first;
     const FeatureConfig& feature_config = element.second;
 
     // Track used event separately.
     if (feature_config.used.name == event_name) {
-      feature_name = feature->name;
+      feature_name = fname;
       DCHECK(!feature_name.empty());
       std::string used_event_action = "InProductHelp.NotifyUsedEvent.";
       used_event_action.append(feature_name);
@@ -67,12 +67,12 @@
     // Find if the |event_name| matches any configuration.
     for (const auto& event : feature_config.event_configs) {
       if (event.name == event_name) {
-        feature_name = feature->name;
+        feature_name = fname;
         break;
       }
     }
     if (feature_config.trigger.name == event_name) {
-      feature_name = feature->name;
+      feature_name = fname;
       break;
     }
   }
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc
index d9a6a04..61297c6e 100644
--- a/components/metrics/file_metrics_provider.cc
+++ b/components/metrics/file_metrics_provider.cc
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "components/metrics/metrics_pref_names.h"
 #include "components/metrics/metrics_service.h"
+#include "components/metrics/persistent_system_profile.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 
@@ -70,6 +71,19 @@
   }
 };
 
+enum EmbeddedProfileResult : int {
+  EMBEDDED_PROFILE_ATTEMPT,
+  EMBEDDED_PROFILE_FOUND,
+  EMBEDDED_PROFILE_FALLBACK,
+  EMBEDDED_PROFILE_DROPPED,
+  EMBEDDED_PROFILE_ACTION_MAX
+};
+
+void RecordEmbeddedProfileResult(EmbeddedProfileResult result) {
+  UMA_HISTOGRAM_ENUMERATION("UMA.FileMetricsProvider.EmbeddedProfileResult",
+                            result, EMBEDDED_PROFILE_ACTION_MAX);
+}
+
 void DeleteFileWhenPossible(const base::FilePath& path) {
   // Open (with delete) and then immediately close the file by going out of
   // scope. This is the only cross-platform safe way to delete a file that may
@@ -84,12 +98,16 @@
 // This structure stores all the information about the sources being monitored
 // and their current reporting state.
 struct FileMetricsProvider::SourceInfo {
-  SourceInfo(SourceType source_type) : type(source_type) {}
+  SourceInfo(SourceType source_type, SourceAssociation source_association)
+      : type(source_type), association(source_association) {}
   ~SourceInfo() {}
 
   // How to access this source (file/dir, atomic/active).
   const SourceType type;
 
+  // With what run this source is associated.
+  const SourceAssociation association;
+
   // Where on disk the directory is located. This will only be populated when
   // a directory is being monitored.
   base::FilePath directory;
@@ -136,7 +154,7 @@
   // Ensure that kSourceOptions has been filled for this type.
   DCHECK_GT(arraysize(kSourceOptions), static_cast<size_t>(type));
 
-  std::unique_ptr<SourceInfo> source(new SourceInfo(type));
+  std::unique_ptr<SourceInfo> source(new SourceInfo(type, source_association));
   source->prefs_key = prefs_key.as_string();
 
   switch (source->type) {
@@ -161,9 +179,11 @@
 
   switch (source_association) {
     case ASSOCIATE_CURRENT_RUN:
+    case ASSOCIATE_INTERNAL_PROFILE:
       sources_to_check_.push_back(std::move(source));
       break;
     case ASSOCIATE_PREVIOUS_RUN:
+    case ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN:
       DCHECK_EQ(SOURCE_HISTOGRAMS_ATOMIC_FILE, source->type);
       sources_for_previous_run_.push_back(std::move(source));
       break;
@@ -250,6 +270,30 @@
 }
 
 // static
+void FileMetricsProvider::FinishedWithSource(SourceInfo* source,
+                                             AccessResult result) {
+  // Different source types require different post-processing.
+  switch (source->type) {
+    case SOURCE_HISTOGRAMS_ATOMIC_FILE:
+    case SOURCE_HISTOGRAMS_ATOMIC_DIR:
+      // Done with this file so delete the allocator and its owned file.
+      source->allocator.reset();
+      // Remove the file if has been recorded. This prevents them from
+      // accumulating or also being recorded by different instances of
+      // the browser.
+      if (result == ACCESS_RESULT_SUCCESS ||
+          result == ACCESS_RESULT_NOT_MODIFIED) {
+        DeleteFileWhenPossible(source->path);
+      }
+      break;
+    case SOURCE_HISTOGRAMS_ACTIVE_FILE:
+      // Keep the allocator open so it doesn't have to be re-mapped each
+      // time. This also allows the contents to be merged on-demand.
+      break;
+  }
+}
+
+// static
 void FileMetricsProvider::CheckAndMergeMetricSourcesOnTaskRunner(
     SourceInfoList* sources) {
   // This method has all state information passed in |sources| and is intended
@@ -264,31 +308,19 @@
           "UMA.FileMetricsProvider.AccessResult", result, ACCESS_RESULT_MAX);
     }
 
+    // Metrics associated with internal profiles have to be fetched directly
+    // so just keep the mapping for use by the main thread.
+    if (source->association == ASSOCIATE_INTERNAL_PROFILE)
+      continue;
+
     // Mapping was successful. Merge it.
     if (result == ACCESS_RESULT_SUCCESS) {
       MergeHistogramDeltasFromSource(source.get());
       DCHECK(source->read_complete);
     }
 
-    // Different source types require different post-processing.
-    switch (source->type) {
-      case SOURCE_HISTOGRAMS_ATOMIC_FILE:
-      case SOURCE_HISTOGRAMS_ATOMIC_DIR:
-        // Done with this file so delete the allocator and its owned file.
-        source->allocator.reset();
-        // Remove the file if has been recorded. This prevents them from
-        // accumulating or also being recorded by different instances of
-        // the browser.
-        if (result == ACCESS_RESULT_SUCCESS ||
-            result == ACCESS_RESULT_NOT_MODIFIED) {
-          base::DeleteFile(source->path, /*recursive=*/false);
-        }
-        break;
-      case SOURCE_HISTOGRAMS_ACTIVE_FILE:
-        // Keep the allocator open so it doesn't have to be re-mapped each
-        // time. This also allows the contents to be merged on-demand.
-        break;
-    }
+    // All done with this source.
+    FinishedWithSource(source.get(), result);
   }
 }
 
@@ -297,8 +329,11 @@
 // static
 FileMetricsProvider::AccessResult FileMetricsProvider::CheckAndMapMetricSource(
     SourceInfo* source) {
-  DCHECK(!source->allocator);
+  // If source was read, clean up after it.
+  if (source->read_complete)
+    FinishedWithSource(source, ACCESS_RESULT_SUCCESS);
   source->read_complete = false;
+  DCHECK(!source->allocator);
 
   // If the source is a directory, look for files within it.
   if (!source->directory.empty() && !LocateNextFileInDirectory(source))
@@ -437,10 +472,16 @@
       RecordSourceAsRead(source);
       did_read = true;
     }
-    if (source->allocator)
-      sources_mapped_.splice(sources_mapped_.end(), *checked, temp);
-    else
+    if (source->allocator) {
+      if (source->association == ASSOCIATE_INTERNAL_PROFILE) {
+        sources_with_profile_.splice(sources_with_profile_.end(), *checked,
+                                     temp);
+      } else {
+        sources_mapped_.splice(sources_mapped_.end(), *checked, temp);
+      }
+    } else {
       sources_to_check_.splice(sources_to_check_.end(), *checked, temp);
+    }
   }
 
   // If a read was done, schedule another one immediately. In the case of a
@@ -487,6 +528,39 @@
   sources_for_previous_run_.clear();
 }
 
+bool FileMetricsProvider::ProvideIndependentMetrics(
+    SystemProfileProto* system_profile_proto,
+    base::HistogramSnapshotManager* snapshot_manager) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  while (!sources_with_profile_.empty()) {
+    SourceInfo* source = sources_with_profile_.begin()->get();
+    DCHECK(source->allocator);
+
+    bool success = false;
+    RecordEmbeddedProfileResult(EMBEDDED_PROFILE_ATTEMPT);
+    if (PersistentSystemProfile::GetSystemProfile(
+            *source->allocator->memory_allocator(), system_profile_proto)) {
+      RecordHistogramSnapshotsFromSource(snapshot_manager, source);
+      success = true;
+      RecordEmbeddedProfileResult(EMBEDDED_PROFILE_FOUND);
+    } else {
+      RecordEmbeddedProfileResult(EMBEDDED_PROFILE_DROPPED);
+    }
+
+    // Regardless of whether this source was successfully recorded, it is never
+    // read again.
+    source->read_complete = true;
+    RecordSourceAsRead(source);
+    sources_to_check_.splice(sources_to_check_.end(), sources_with_profile_,
+                             sources_with_profile_.begin());
+    if (success)
+      return true;
+  }
+
+  return false;
+}
+
 bool FileMetricsProvider::HasInitialStabilityMetrics() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
@@ -521,6 +595,21 @@
       RecordSourceAsRead(source);
       DeleteFileAsync(source->path);
       sources_for_previous_run_.erase(temp);
+      continue;
+    }
+
+    DCHECK(source->allocator);
+
+    // If the source should be associated with an existing internal profile,
+    // move it to |sources_with_profile_| for later upload.
+    if (source->association == ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN) {
+      if (PersistentSystemProfile::HasSystemProfile(
+              *source->allocator->memory_allocator())) {
+        RecordEmbeddedProfileResult(EMBEDDED_PROFILE_ATTEMPT);
+        RecordEmbeddedProfileResult(EMBEDDED_PROFILE_FALLBACK);
+        sources_with_profile_.splice(sources_with_profile_.end(),
+                                     sources_for_previous_run_, temp);
+      }
     }
   }
 
diff --git a/components/metrics/file_metrics_provider.h b/components/metrics/file_metrics_provider.h
index 43d4d30..a19577b 100644
--- a/components/metrics/file_metrics_provider.h
+++ b/components/metrics/file_metrics_provider.h
@@ -80,6 +80,19 @@
     // This is important when metrics are dumped as part of a crash of the
     // previous run. This can only be used with FILE_HISTOGRAMS_ATOMIC.
     ASSOCIATE_PREVIOUS_RUN,
+
+    // Associates the metrics in the file with the a profile embedded in the
+    // same file. The reporting will take place at a convenient time after
+    // startup when the browser is otherwise idle. If there is no embedded
+    // system profile, these metrics will be lost.
+    ASSOCIATE_INTERNAL_PROFILE,
+
+    // Like above but fall back to ASSOCIATE_PREVIOUS_RUN if there is no
+    // embedded profile. This has a small cost during startup as that is
+    // when previous-run metrics are sent so the file has be checked at
+    // that time even though actual transfer will be delayed if an
+    // embedded profile is found.
+    ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN,
   };
 
   FileMetricsProvider(const scoped_refptr<base::TaskRunner>& task_runner,
@@ -147,6 +160,9 @@
   // be internally updated to indicate the next file to be read.
   static bool LocateNextFileInDirectory(SourceInfo* source);
 
+  // Handles the completion of a source.
+  static void FinishedWithSource(SourceInfo* source, AccessResult result);
+
   // Checks a list of sources (on a task-runner allowed to do I/O) and merge
   // any data found within them.
   static void CheckAndMergeMetricSourcesOnTaskRunner(SourceInfoList* sources);
@@ -175,8 +191,11 @@
   // Updates the persistent state information to show a source as being read.
   void RecordSourceAsRead(SourceInfo* source);
 
-  // metrics::MetricsDataProvider:
+  // metrics::MetricsProvider:
   void OnDidCreateMetricsLog() override;
+  bool ProvideIndependentMetrics(
+      SystemProfileProto* system_profile_proto,
+      base::HistogramSnapshotManager* snapshot_manager) override;
   bool HasInitialStabilityMetrics() override;
   void RecordInitialHistogramSnapshots(
       base::HistogramSnapshotManager* snapshot_manager) override;
@@ -193,6 +212,9 @@
   // A list of currently active sources to be merged when required.
   SourceInfoList sources_mapped_;
 
+  // A list of currently active sources to be merged when required.
+  SourceInfoList sources_with_profile_;
+
   // A list of sources for a previous run. These are held separately because
   // they are not subject to the periodic background checking that handles
   // metrics for the current run.
diff --git a/components/metrics/file_metrics_provider_unittest.cc b/components/metrics/file_metrics_provider_unittest.cc
index 9781cea..2b6fbdb 100644
--- a/components/metrics/file_metrics_provider_unittest.cc
+++ b/components/metrics/file_metrics_provider_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/metrics/file_metrics_provider.h"
 
+#include <functional>
+
 #include "base/files/file_util.h"
 #include "base/files/memory_mapped_file.h"
 #include "base/files/scoped_temp_dir.h"
@@ -20,6 +22,8 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
 #include "components/metrics/metrics_pref_names.h"
+#include "components/metrics/persistent_system_profile.h"
+#include "components/metrics/proto/system_profile.pb.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -118,6 +122,13 @@
     provider()->MergeHistogramDeltas();
   }
 
+  bool ProvideIndependentMetrics(
+      SystemProfileProto* profile_proto,
+      base::HistogramSnapshotManager* snapshot_manager) {
+    return provider()->ProvideIndependentMetrics(profile_proto,
+                                                 snapshot_manager);
+  }
+
   void RecordInitialHistogramSnapshots(
       base::HistogramSnapshotManager* snapshot_manager) {
     provider()->RecordInitialHistogramSnapshots(snapshot_manager);
@@ -176,7 +187,10 @@
   }
 
   std::unique_ptr<base::PersistentHistogramAllocator>
-  CreateMetricsFileWithHistograms(int histogram_count) {
+  CreateMetricsFileWithHistograms(
+      int histogram_count,
+      const std::function<void(base::PersistentHistogramAllocator*)>&
+          callback) {
     // Get this first so it isn't created inside the persistent allocator.
     base::GlobalHistogramAllocator::GetCreateHistogramResultHistogram();
 
@@ -188,10 +202,18 @@
 
     std::unique_ptr<base::PersistentHistogramAllocator> histogram_allocator =
         base::GlobalHistogramAllocator::ReleaseForTesting();
+    callback(histogram_allocator.get());
+
     WriteMetricsFile(metrics_file(), histogram_allocator.get());
     return histogram_allocator;
   }
 
+  std::unique_ptr<base::PersistentHistogramAllocator>
+  CreateMetricsFileWithHistograms(int histogram_count) {
+    return CreateMetricsFileWithHistograms(
+        histogram_count, [](base::PersistentHistogramAllocator* allocator) {});
+  }
+
   base::HistogramBase* GetCreatedHistogram(int index) {
     DCHECK_GT(kMaxCreateHistograms, index);
     return created_histograms_[index];
@@ -411,7 +433,7 @@
                              kMetricsName);
 
   // Record embedded snapshots via snapshot-manager.
-  HasInitialStabilityMetrics();
+  ASSERT_TRUE(HasInitialStabilityMetrics());
   RunTasks();
   {
     HistogramFlattenerDeltaRecorder flattener;
@@ -435,4 +457,144 @@
   EXPECT_TRUE(base::PathExists(metrics_file()));
 }
 
+TEST_P(FileMetricsProviderTest, AccessEmbeddedProfileMetricsWithoutProfile) {
+  ASSERT_FALSE(PathExists(metrics_file()));
+  CreateMetricsFileWithHistograms(2);
+
+  // Register the file and allow the "checker" task to run.
+  ASSERT_TRUE(PathExists(metrics_file()));
+  provider()->RegisterSource(
+      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
+      FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName);
+
+  // Record embedded snapshots via snapshot-manager.
+  OnDidCreateMetricsLog();
+  RunTasks();
+  {
+    HistogramFlattenerDeltaRecorder flattener;
+    base::HistogramSnapshotManager snapshot_manager(&flattener);
+    SystemProfileProto profile;
+
+    // A read of metrics with internal profiles should return nothing.
+    EXPECT_FALSE(ProvideIndependentMetrics(&profile, &snapshot_manager));
+  }
+  EXPECT_TRUE(base::PathExists(metrics_file()));
+  OnDidCreateMetricsLog();
+  RunTasks();
+  EXPECT_FALSE(base::PathExists(metrics_file()));
+}
+
+TEST_P(FileMetricsProviderTest, AccessEmbeddedProfileMetricsWithProfile) {
+  ASSERT_FALSE(PathExists(metrics_file()));
+  CreateMetricsFileWithHistograms(
+      2, [](base::PersistentHistogramAllocator* allocator) {
+        SystemProfileProto profile_proto;
+        SystemProfileProto::FieldTrial* trial = profile_proto.add_field_trial();
+        trial->set_name_id(123);
+        trial->set_group_id(456);
+
+        PersistentSystemProfile persistent_profile;
+        persistent_profile.RegisterPersistentAllocator(
+            allocator->memory_allocator());
+        persistent_profile.SetSystemProfile(profile_proto);
+      });
+
+  // Register the file and allow the "checker" task to run.
+  ASSERT_TRUE(PathExists(metrics_file()));
+  provider()->RegisterSource(
+      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
+      FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE, kMetricsName);
+
+  // Record embedded snapshots via snapshot-manager.
+  OnDidCreateMetricsLog();
+  RunTasks();
+  {
+    HistogramFlattenerDeltaRecorder flattener;
+    base::HistogramSnapshotManager snapshot_manager(&flattener);
+    RecordInitialHistogramSnapshots(&snapshot_manager);
+    EXPECT_EQ(0U, flattener.GetRecordedDeltaHistogramNames().size());
+
+    // A read of metrics with internal profiles should return one result.
+    SystemProfileProto profile;
+    EXPECT_TRUE(ProvideIndependentMetrics(&profile, &snapshot_manager));
+    EXPECT_FALSE(ProvideIndependentMetrics(&profile, &snapshot_manager));
+  }
+  EXPECT_TRUE(base::PathExists(metrics_file()));
+  OnDidCreateMetricsLog();
+  RunTasks();
+  EXPECT_FALSE(base::PathExists(metrics_file()));
+}
+
+TEST_P(FileMetricsProviderTest, AccessEmbeddedFallbackMetricsWithoutProfile) {
+  ASSERT_FALSE(PathExists(metrics_file()));
+  CreateMetricsFileWithHistograms(2);
+
+  // Register the file and allow the "checker" task to run.
+  ASSERT_TRUE(PathExists(metrics_file()));
+  provider()->RegisterSource(
+      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
+      FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN,
+      kMetricsName);
+
+  // Record embedded snapshots via snapshot-manager.
+  ASSERT_TRUE(HasInitialStabilityMetrics());
+  RunTasks();
+  {
+    HistogramFlattenerDeltaRecorder flattener;
+    base::HistogramSnapshotManager snapshot_manager(&flattener);
+    RecordInitialHistogramSnapshots(&snapshot_manager);
+    EXPECT_EQ(2U, flattener.GetRecordedDeltaHistogramNames().size());
+
+    // A read of metrics with internal profiles should return nothing.
+    SystemProfileProto profile;
+    EXPECT_FALSE(ProvideIndependentMetrics(&profile, &snapshot_manager));
+  }
+  EXPECT_TRUE(base::PathExists(metrics_file()));
+  OnDidCreateMetricsLog();
+  RunTasks();
+  EXPECT_FALSE(base::PathExists(metrics_file()));
+}
+
+TEST_P(FileMetricsProviderTest, AccessEmbeddedFallbackMetricsWithProfile) {
+  ASSERT_FALSE(PathExists(metrics_file()));
+  CreateMetricsFileWithHistograms(
+      2, [](base::PersistentHistogramAllocator* allocator) {
+        SystemProfileProto profile_proto;
+        SystemProfileProto::FieldTrial* trial = profile_proto.add_field_trial();
+        trial->set_name_id(123);
+        trial->set_group_id(456);
+
+        PersistentSystemProfile persistent_profile;
+        persistent_profile.RegisterPersistentAllocator(
+            allocator->memory_allocator());
+        persistent_profile.SetSystemProfile(profile_proto);
+      });
+
+  // Register the file and allow the "checker" task to run.
+  ASSERT_TRUE(PathExists(metrics_file()));
+  provider()->RegisterSource(
+      metrics_file(), FileMetricsProvider::SOURCE_HISTOGRAMS_ATOMIC_FILE,
+      FileMetricsProvider::ASSOCIATE_INTERNAL_PROFILE_OR_PREVIOUS_RUN,
+      kMetricsName);
+
+  // Record embedded snapshots via snapshot-manager.
+  EXPECT_FALSE(HasInitialStabilityMetrics());
+  RunTasks();
+  {
+    HistogramFlattenerDeltaRecorder flattener;
+    base::HistogramSnapshotManager snapshot_manager(&flattener);
+    RecordInitialHistogramSnapshots(&snapshot_manager);
+    EXPECT_EQ(0U, flattener.GetRecordedDeltaHistogramNames().size());
+
+    // A read of metrics with internal profiles should return one result.
+    SystemProfileProto profile;
+    EXPECT_TRUE(ProvideIndependentMetrics(&profile, &snapshot_manager));
+    EXPECT_FALSE(ProvideIndependentMetrics(&profile, &snapshot_manager));
+  }
+  EXPECT_TRUE(base::PathExists(metrics_file()));
+  OnDidCreateMetricsLog();
+  RunTasks();
+  EXPECT_FALSE(base::PathExists(metrics_file()));
+}
+
 }  // namespace metrics
diff --git a/components/metrics/metrics_log.cc b/components/metrics/metrics_log.cc
index 0523372..4d3123c 100644
--- a/components/metrics/metrics_log.cc
+++ b/components/metrics/metrics_log.cc
@@ -11,8 +11,11 @@
 
 #include "base/build_time.h"
 #include "base/cpu.h"
+#include "base/metrics/histogram_base.h"
+#include "base/metrics/histogram_flattener.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/histogram_samples.h"
+#include "base/metrics/histogram_snapshot_manager.h"
 #include "base/metrics/metrics_hashes.h"
 #include "base/sys_info.h"
 #include "base/time/time.h"
@@ -51,6 +54,28 @@
 
 namespace {
 
+// A simple class to write histogram data to a log.
+class IndependentFlattener : public base::HistogramFlattener {
+ public:
+  explicit IndependentFlattener(MetricsLog* log) : log_(log) {}
+
+  // base::HistogramFlattener:
+  void RecordDelta(const base::HistogramBase& histogram,
+                   const base::HistogramSamples& snapshot) override {
+    log_->RecordHistogramDelta(histogram.histogram_name(), snapshot);
+  }
+  void InconsistencyDetected(
+      base::HistogramBase::Inconsistency problem) override {}
+  void UniqueInconsistencyDetected(
+      base::HistogramBase::Inconsistency problem) override {}
+  void InconsistencyDetectedInLoggedCount(int amount) override {}
+
+ private:
+  MetricsLog* const log_;
+
+  DISALLOW_COPY_AND_ASSIGN(IndependentFlattener);
+};
+
 // Any id less than 16 bytes is considered to be a testing id.
 bool IsTestingID(const std::string& id) {
   return id.size() < 16;
@@ -319,6 +344,15 @@
   return serialized_proto;
 }
 
+bool MetricsLog::LoadIndependentMetrics(MetricsProvider* metrics_provider) {
+  SystemProfileProto* system_profile = uma_proto()->mutable_system_profile();
+  IndependentFlattener flattener(this);
+  base::HistogramSnapshotManager snapshot_manager(&flattener);
+
+  return metrics_provider->ProvideIndependentMetrics(system_profile,
+                                                     &snapshot_manager);
+}
+
 bool MetricsLog::LoadSavedEnvironmentFromPrefs(std::string* app_version) {
   DCHECK(app_version);
   app_version->clear();
diff --git a/components/metrics/metrics_log.h b/components/metrics/metrics_log.h
index 441cfbc..688a624 100644
--- a/components/metrics/metrics_log.h
+++ b/components/metrics/metrics_log.h
@@ -44,6 +44,7 @@
   enum LogType {
     INITIAL_STABILITY_LOG,  // The initial log containing stability stats.
     ONGOING_LOG,            // Subsequent logs in a session.
+    INDEPENDENT_LOG,        // An independent log from a previous session.
   };
 
   // Creates a new metrics log of the specified type.
@@ -105,6 +106,11 @@
       int64_t install_date,
       int64_t metrics_reporting_enabled_date);
 
+  // Loads a saved system profile and the associated metrics into the log.
+  // Returns true on success. Keep calling it with fresh logs until it returns
+  // false.
+  bool LoadIndependentMetrics(MetricsProvider* metrics_provider);
+
   // Loads the environment proto that was saved by the last RecordEnvironment()
   // call from prefs. On success, returns true and |app_version| contains the
   // recovered version. Otherwise (if there was no saved environment in prefs
diff --git a/components/metrics/metrics_log_store.cc b/components/metrics/metrics_log_store.cc
index 8b1ec2a7..30cbe6c 100644
--- a/components/metrics/metrics_log_store.cc
+++ b/components/metrics/metrics_log_store.cc
@@ -73,6 +73,7 @@
       initial_log_queue_.StoreLog(log_data);
       break;
     case MetricsLog::ONGOING_LOG:
+    case MetricsLog::INDEPENDENT_LOG:
       ongoing_log_queue_.StoreLog(log_data);
       break;
   }
diff --git a/components/metrics/metrics_provider.cc b/components/metrics/metrics_provider.cc
index fd864e41..c5ca585 100644
--- a/components/metrics/metrics_provider.cc
+++ b/components/metrics/metrics_provider.cc
@@ -27,6 +27,12 @@
 void MetricsProvider::OnAppEnterBackground() {
 }
 
+bool MetricsProvider::ProvideIndependentMetrics(
+    SystemProfileProto* system_profile_proto,
+    base::HistogramSnapshotManager* snapshot_manager) {
+  return false;
+}
+
 void MetricsProvider::ProvideSystemProfileMetrics(
     SystemProfileProto* system_profile_proto) {
 }
diff --git a/components/metrics/metrics_provider.h b/components/metrics/metrics_provider.h
index 54c0a894..a867ef4 100644
--- a/components/metrics/metrics_provider.h
+++ b/components/metrics/metrics_provider.h
@@ -42,6 +42,14 @@
   // further notification after this callback.
   virtual void OnAppEnterBackground();
 
+  // Provides a complete and independent system profile + metrics for uploading.
+  // Any histograms added to the |snapshot_manager| will also be included. A
+  // return of false indicates there are none. Will be called repeatedly until
+  // there is nothing else.
+  virtual bool ProvideIndependentMetrics(
+      SystemProfileProto* system_profile_proto,
+      base::HistogramSnapshotManager* snapshot_manager);
+
   // Provides additional metrics into the system profile.
   virtual void ProvideSystemProfileMetrics(
       SystemProfileProto* system_profile_proto);
diff --git a/components/metrics/metrics_service.cc b/components/metrics/metrics_service.cc
index f489d16..6a44e35 100644
--- a/components/metrics/metrics_service.cc
+++ b/components/metrics/metrics_service.cc
@@ -625,6 +625,12 @@
         FROM_HERE, base::Bind(&MetricsService::StartInitTask,
                               self_ptr_factory_.GetWeakPtr()),
         base::TimeDelta::FromSeconds(kInitializationDelaySeconds));
+
+    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&MetricsService::PrepareProviderMetricsTask,
+                   self_ptr_factory_.GetWeakPtr()),
+        base::TimeDelta::FromSeconds(2 * kInitializationDelaySeconds));
   }
 }
 
@@ -971,6 +977,37 @@
     provider->RecordInitialHistogramSnapshots(&histogram_snapshot_manager_);
 }
 
+bool MetricsService::PrepareProviderMetricsLog() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  // Create a new log. This will have some defaut values injected in it but
+  // those will be overwritten when an embedded profile is extracted.
+  std::unique_ptr<MetricsLog> log = CreateLog(MetricsLog::INDEPENDENT_LOG);
+
+  for (auto& provider : metrics_providers_) {
+    if (log->LoadIndependentMetrics(provider.get())) {
+      log_manager_.PauseCurrentLog();
+      log_manager_.BeginLoggingWithLog(std::move(log));
+      log_manager_.FinishCurrentLog(log_store());
+      log_manager_.ResumePausedLog();
+      return true;
+    }
+  }
+  return false;
+}
+
+void MetricsService::PrepareProviderMetricsTask() {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  bool found = PrepareProviderMetricsLog();
+  base::TimeDelta next_check = found ? base::TimeDelta::FromSeconds(5)
+                                     : base::TimeDelta::FromMinutes(15);
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&MetricsService::PrepareProviderMetricsTask,
+                 self_ptr_factory_.GetWeakPtr()),
+      next_check);
+}
+
 void MetricsService::LogCleanShutdown(bool end_completed) {
   DCHECK(thread_checker_.CalledOnValidThread());
   // Redundant setting to assure that we always reset this value at shutdown
diff --git a/components/metrics/metrics_service.h b/components/metrics/metrics_service.h
index f95fd6d..102ab72 100644
--- a/components/metrics/metrics_service.h
+++ b/components/metrics/metrics_service.h
@@ -353,6 +353,15 @@
   // i.e., histograms with the |kUmaStabilityHistogramFlag| flag set.
   void RecordCurrentStabilityHistograms();
 
+  // Record a single independent profile and assocatied histogram from
+  // metrics providers. If this returns true, one was found and there may
+  // be more.
+  bool PrepareProviderMetricsLog();
+
+  // Records one independent histogram log and then reschedules itself to
+  // check for others. The interval is so as to not adversely impact the UI.
+  void PrepareProviderMetricsTask();
+
   // Sub-service for uploading logs.
   MetricsReportingService reporting_service_;
 
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc
index 747e38b..e426789 100644
--- a/components/metrics/metrics_service_unittest.cc
+++ b/components/metrics/metrics_service_unittest.cc
@@ -491,45 +491,46 @@
   service.Start();
   // Rotation loop should create a log and mark state as idle.
   // Upload loop should start upload or be restarted.
+  // The independent-metrics upload job will be started and always be a task.
   task_runner_->RunPendingTasks();
   // Rotation loop should terminated due to being idle.
   // Upload loop should start uploading if it isn't already.
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(client.uploader()->is_uploading());
-  EXPECT_EQ(0U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
   service.OnApplicationNotIdle();
   EXPECT_TRUE(client.uploader()->is_uploading());
-  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(2U, task_runner_->NumPendingTasks());
   // Log generation should be suppressed due to unsent log.
   // Idle state should not be reset.
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(client.uploader()->is_uploading());
-  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(2U, task_runner_->NumPendingTasks());
   // Make sure idle state was not reset.
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(client.uploader()->is_uploading());
-  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(2U, task_runner_->NumPendingTasks());
   // Upload should not be rescheduled, since there are no other logs.
   client.uploader()->CompleteUpload(200);
   EXPECT_FALSE(client.uploader()->is_uploading());
-  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(2U, task_runner_->NumPendingTasks());
   // Running should generate a log, restart upload loop, and mark idle.
   task_runner_->RunPendingTasks();
   EXPECT_FALSE(client.uploader()->is_uploading());
-  EXPECT_EQ(2U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(3U, task_runner_->NumPendingTasks());
   // Upload should start, and rotation loop should idle out.
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(client.uploader()->is_uploading());
-  EXPECT_EQ(0U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
   // Uploader should reschedule when there is another log available.
   service.PushExternalLog("Blah");
   client.uploader()->CompleteUpload(200);
   EXPECT_FALSE(client.uploader()->is_uploading());
-  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(2U, task_runner_->NumPendingTasks());
   // Upload should start.
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(client.uploader()->is_uploading());
-  EXPECT_EQ(0U, task_runner_->NumPendingTasks());
+  EXPECT_EQ(1U, task_runner_->NumPendingTasks());
 }
 
 TEST_F(MetricsServiceTest, GetSyntheticFieldTrialActiveGroups) {
diff --git a/components/metrics/persistent_system_profile.cc b/components/metrics/persistent_system_profile.cc
index 526b1407..dc4e7eb 100644
--- a/components/metrics/persistent_system_profile.cc
+++ b/components/metrics/persistent_system_profile.cc
@@ -101,6 +101,22 @@
   return true;
 }
 
+bool PersistentSystemProfile::RecordAllocator::HasMoreData() const {
+  if (alloc_reference_ == 0 && !NextSegment())
+    return false;
+
+  char* block =
+      allocator_->GetAsArray<char>(alloc_reference_, kTypeIdSystemProfile,
+                                   base::PersistentMemoryAllocator::kSizeAny);
+  if (!block)
+    return false;
+
+  RecordHeader header;
+  header.as_atomic = base::subtle::Acquire_Load(
+      reinterpret_cast<base::subtle::Atomic32*>(block + end_offset_));
+  return header.as_parts.type != kUnusedSpace;
+}
+
 bool PersistentSystemProfile::RecordAllocator::Read(RecordType* type,
                                                     std::string* record) const {
   *type = kUnusedSpace;
@@ -276,6 +292,21 @@
   }
 }
 
+void PersistentSystemProfile::SetSystemProfile(
+    const SystemProfileProto& profile) {
+  std::string serialized_profile;
+  if (!profile.SerializeToString(&serialized_profile))
+    return;
+  SetSystemProfile(serialized_profile);
+}
+
+// static
+bool PersistentSystemProfile::HasSystemProfile(
+    const base::PersistentMemoryAllocator& memory_allocator) {
+  const RecordAllocator records(&memory_allocator);
+  return records.HasMoreData();
+}
+
 // static
 bool PersistentSystemProfile::GetSystemProfile(
     const base::PersistentMemoryAllocator& memory_allocator,
diff --git a/components/metrics/persistent_system_profile.h b/components/metrics/persistent_system_profile.h
index 30d971f6..1775dde 100644
--- a/components/metrics/persistent_system_profile.h
+++ b/components/metrics/persistent_system_profile.h
@@ -30,8 +30,14 @@
   void DeregisterPersistentAllocator(
       base::PersistentMemoryAllocator* memory_allocator);
 
-  // Stores a complete system profile.
+  // Stores a complete system profile. Use the version taking the serialized
+  // version if available to avoid multiple serialization actions.
   void SetSystemProfile(const std::string& serialized_profile);
+  void SetSystemProfile(const SystemProfileProto& profile);
+
+  // Tests if a persistent memory allocator contains an system profile.
+  static bool HasSystemProfile(
+      const base::PersistentMemoryAllocator& memory_allocator);
 
   // Retrieves the system profile from a persistent memory allocator. Returns
   // true if a profile was successfully retrieved.
@@ -65,6 +71,7 @@
 
     // Read a record from the allocator. Do not mix this with "write" calls;
     // it's one or the other.
+    bool HasMoreData() const;
     bool Read(RecordType* type, std::string* record) const;
 
     base::PersistentMemoryAllocator* allocator() { return allocator_; }
diff --git a/components/metrics/persistent_system_profile_unittest.cc b/components/metrics/persistent_system_profile_unittest.cc
index 93f297a..5ca4e898 100644
--- a/components/metrics/persistent_system_profile_unittest.cc
+++ b/components/metrics/persistent_system_profile_unittest.cc
@@ -91,11 +91,10 @@
   trial->set_name_id(123);
   trial->set_group_id(456);
 
-  std::string serialized_proto;
-  ASSERT_TRUE(proto1.SerializeToString(&serialized_proto));
-  persistent_profile()->SetSystemProfile(serialized_proto);
+  persistent_profile()->SetSystemProfile(proto1);
 
   SystemProfileProto proto2;
+  ASSERT_TRUE(PersistentSystemProfile::HasSystemProfile(*memory_allocator()));
   ASSERT_TRUE(
       PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &proto2));
   ASSERT_EQ(1, proto2.field_trial_size());
@@ -108,8 +107,7 @@
   trial->set_name_id(78);
   trial->set_group_id(90);
 
-  ASSERT_TRUE(proto1.SerializeToString(&serialized_proto));
-  persistent_profile()->SetSystemProfile(serialized_proto);
+  persistent_profile()->SetSystemProfile(proto1);
 
   ASSERT_TRUE(
       PersistentSystemProfile::GetSystemProfile(*memory_allocator(), &proto2));
diff --git a/components/omnibox/browser/omnibox_view.h b/components/omnibox/browser/omnibox_view.h
index 03d358c..58acdfc 100644
--- a/components/omnibox/browser/omnibox_view.h
+++ b/components/omnibox/browser/omnibox_view.h
@@ -31,10 +31,6 @@
 class OmniboxViewMacTest;
 class OmniboxEditModel;
 
-namespace gfx {
-enum class VectorIconId;
-}
-
 class OmniboxView {
  public:
   // Represents the changes between two State objects.  This is used by the
diff --git a/components/password_manager/core/browser/affiliation_utils.h b/components/password_manager/core/browser/affiliation_utils.h
index 4d463c9..960d347 100644
--- a/components/password_manager/core/browser/affiliation_utils.h
+++ b/components/password_manager/core/browser/affiliation_utils.h
@@ -66,7 +66,7 @@
 //
 // This is a very light-weight wrapper around an std::string containing the text
 // of the URI, and can be passed around as a value. The main rationale for the
-// existance of this class is to make it clearer in the code when a certain URI
+// existence of this class is to make it clearer in the code when a certain URI
 // is known to be a valid facet URI in canonical form, and to allow verifying
 // and converting URIs to such canonical form.
 //
diff --git a/components/payments/mojom/payment_request.mojom b/components/payments/mojom/payment_request.mojom
index 72c3dac..639e544f 100644
--- a/components/payments/mojom/payment_request.mojom
+++ b/components/payments/mojom/payment_request.mojom
@@ -176,6 +176,8 @@
   array<AndroidPayTokenizationParameter> parameters;
   // Value of 0 means the merchant did not specify or it was an invalid value.
   int32 min_google_play_services_version;
+  // Value of 0 means the merchant did not specify or it was an invalid value.
+  int32 api_version;
 
   // Basic card specific method data is parsed in the renderer.
   array<BasicCardNetwork> supported_networks;
diff --git a/components/sync/device_info/device_info_sync_bridge_unittest.cc b/components/sync/device_info/device_info_sync_bridge_unittest.cc
index aa1d2936..50df566c 100644
--- a/components/sync/device_info/device_info_sync_bridge_unittest.cc
+++ b/components/sync/device_info/device_info_sync_bridge_unittest.cc
@@ -617,7 +617,7 @@
               *bridge()->GetDeviceInfo(unique_remote.cache_guid()).get());
   VerifyEqual(conflict_remote, *bridge()->GetDeviceInfo(conflict_guid).get());
 
-  // bridge should have told the processor about the existance of unique_local.
+  // bridge should have told the processor about the existence of unique_local.
   EXPECT_TRUE(processor().delete_set().empty());
   EXPECT_EQ(3u, processor().put_multimap().size());
   EXPECT_EQ(1u, processor().put_multimap().count(unique_local.cache_guid()));
diff --git a/components/toolbar/toolbar_model_delegate.h b/components/toolbar/toolbar_model_delegate.h
index 8c61c45..91008e4 100644
--- a/components/toolbar/toolbar_model_delegate.h
+++ b/components/toolbar/toolbar_model_delegate.h
@@ -50,10 +50,10 @@
   // Returns true if the current page fails the malware check.
   virtual bool FailsMalwareCheck() const = 0;
 
-  // Returns the id of the icon to show to the left of the address, or
-  // gfx::VectorIconId::VECTOR_ICON_NONE if the icon should be selected by the
-  // caller. This is useful for associating particular URLs with particular
-  // schemes without importing knowledge of those schemes into this component.
+  // Returns the id of the icon to show to the left of the address, or nullptr
+  // if the icon should be selected by the caller. This is useful for
+  // associating particular URLs with particular schemes without importing
+  // knowledge of those schemes into this component.
   virtual const gfx::VectorIcon* GetVectorIconOverride() const = 0;
 
  protected:
diff --git a/components/translate/core/browser/translate_ranker_impl.cc b/components/translate/core/browser/translate_ranker_impl.cc
index f8ee2067..0b6a89e 100644
--- a/components/translate/core/browser/translate_ranker_impl.cc
+++ b/components/translate/core/browser/translate_ranker_impl.cc
@@ -146,6 +146,8 @@
         base::Bind(&TranslateRankerImpl::OnModelAvailable,
                    weak_ptr_factory_.GetWeakPtr()),
         model_path, model_url, kUmaPrefix);
+    // Kick off the initial load from cache.
+    model_loader_->NotifyOfRankerActivity();
   }
 }
 
diff --git a/components/ui_metrics/BUILD.gn b/components/ui_metrics/BUILD.gn
new file mode 100644
index 0000000..941ed1c
--- /dev/null
+++ b/components/ui_metrics/BUILD.gn
@@ -0,0 +1,9 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("ui_metrics") {
+  sources = [
+    "sadtab_metrics_types.h",
+  ]
+}
diff --git a/components/ui_metrics/sadtab_metrics_types.h b/components/ui_metrics/sadtab_metrics_types.h
new file mode 100644
index 0000000..056541a
--- /dev/null
+++ b/components/ui_metrics/sadtab_metrics_types.h
@@ -0,0 +1,28 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UI_METRICS_SADTAB_METRICS_TYPES_H_
+#define COMPONENTS_UI_METRICS_SADTAB_METRICS_TYPES_H_
+
+namespace ui_metrics {
+// An enum for reporting interaction events to a UMA histogram.
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.tab
+enum class SadTabEvent {
+  // Records that the Sad Tab was displayed.
+  DISPLAYED = 0,
+  // Records that the main Sad Tab button was triggered.
+  BUTTON_CLICKED = 1,
+  // Records that the Sad Tab help link was triggered.
+  HELP_LINK_CLICKED = 2,
+  // Enum end marker.
+  MAX_SAD_TAB_EVENT = 3,
+};
+
+// Describes the mode of the Sad Tab as being in 'reload' mode.
+const char kSadTabReloadHistogramKey[] = "Tabs.SadTab.Reload.Event";
+// Describes the mode of the Sad Tab as being in 'feedback' mode.
+const char kSadTabFeedbackHistogramKey[] = "Tabs.SadTab.Feedback.Event";
+}
+
+#endif  // COMPONENTS_UI_METRICS_SADTAB_METRICS_TYPES_H_
diff --git a/components/viz/display_compositor/gpu_display_provider.cc b/components/viz/display_compositor/gpu_display_provider.cc
index f89ff10..483eaaa8 100644
--- a/components/viz/display_compositor/gpu_display_provider.cc
+++ b/components/viz/display_compositor/gpu_display_provider.cc
@@ -74,8 +74,9 @@
       display_output_surface->capabilities().max_frames_pending;
   DCHECK_GT(max_frames_pending, 0);
 
-  auto scheduler = base::MakeUnique<cc::DisplayScheduler>(task_runner_.get(),
-                                                          max_frames_pending);
+  auto scheduler = base::MakeUnique<cc::DisplayScheduler>(
+      synthetic_begin_frame_source.get(), task_runner_.get(),
+      max_frames_pending);
 
   cc::RendererSettings settings;
   settings.show_overdraw_feedback =
@@ -87,8 +88,8 @@
 
   return base::MakeUnique<cc::Display>(
       HostSharedBitmapManager::current(), gpu_memory_buffer_manager_.get(),
-      settings, frame_sink_id, begin_frame_source->get(),
-      std::move(display_output_surface), std::move(scheduler),
+      settings, frame_sink_id, std::move(display_output_surface),
+      std::move(scheduler),
       base::MakeUnique<cc::TextureMailboxDeleter>(task_runner_.get()));
 }
 
diff --git a/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
index 0fd4bfa5..2804a0f 100644
--- a/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
+++ b/components/viz/frame_sinks/gpu_root_compositor_frame_sink.cc
@@ -36,16 +36,22 @@
           this,
           std::move(compositor_frame_sink_private_request)),
       display_private_binding_(this, std::move(display_private_request)) {
+  DCHECK(display_begin_frame_source_);
   compositor_frame_sink_binding_.set_connection_error_handler(
       base::Bind(&GpuRootCompositorFrameSink::OnClientConnectionLost,
                  base::Unretained(this)));
   compositor_frame_sink_private_binding_.set_connection_error_handler(
       base::Bind(&GpuRootCompositorFrameSink::OnPrivateConnectionLost,
                  base::Unretained(this)));
+  surface_manager->RegisterBeginFrameSource(display_begin_frame_source_.get(),
+                                            frame_sink_id);
   display_->Initialize(this, surface_manager);
 }
 
-GpuRootCompositorFrameSink::~GpuRootCompositorFrameSink() = default;
+GpuRootCompositorFrameSink::~GpuRootCompositorFrameSink() {
+  support_->surface_manager()->UnregisterBeginFrameSource(
+      display_begin_frame_source_.get());
+}
 
 void GpuRootCompositorFrameSink::SetDisplayVisible(bool visible) {
   DCHECK(display_);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 8f609b8f..307a1e7 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -539,6 +539,8 @@
     "devtools/protocol/io_handler.h",
     "devtools/protocol/memory_handler.cc",
     "devtools/protocol/memory_handler.h",
+    "devtools/protocol/native_input_event_builder.h",
+    "devtools/protocol/native_input_event_builder_mac.mm",
     "devtools/protocol/network_handler.cc",
     "devtools/protocol/network_handler.h",
     "devtools/protocol/page_handler.cc",
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index 417dc0f..2f56033 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -591,18 +591,27 @@
   gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild(
       compositor->widget());
 #endif
+  if (data->synthetic_begin_frame_source) {
+    GetSurfaceManager()->UnregisterBeginFrameSource(
+        data->synthetic_begin_frame_source.get());
+  } else if (data->gpu_vsync_begin_frame_source) {
+    GetSurfaceManager()->UnregisterBeginFrameSource(
+        data->gpu_vsync_begin_frame_source.get());
+  }
 
   std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
-      compositor->task_runner().get(),
+      begin_frame_source, compositor->task_runner().get(),
       display_output_surface->capabilities().max_frames_pending));
 
   // The Display owns and uses the |display_output_surface| created above.
   data->display = base::MakeUnique<cc::Display>(
       viz::HostSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
-      renderer_settings_, compositor->frame_sink_id(), begin_frame_source,
+      renderer_settings_, compositor->frame_sink_id(),
       std::move(display_output_surface), std::move(scheduler),
       base::MakeUnique<cc::TextureMailboxDeleter>(
           compositor->task_runner().get()));
+  GetSurfaceManager()->RegisterBeginFrameSource(begin_frame_source,
+                                                compositor->frame_sink_id());
   // Note that we are careful not to destroy prior BeginFrameSource objects
   // until we have reset |data->display|.
   data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
@@ -662,7 +671,13 @@
   if (data->surface_handle)
     gpu::GpuSurfaceTracker::Get()->RemoveSurface(data->surface_handle);
 #endif
-
+  if (data->synthetic_begin_frame_source) {
+    GetSurfaceManager()->UnregisterBeginFrameSource(
+        data->synthetic_begin_frame_source.get());
+  } else if (data->gpu_vsync_begin_frame_source) {
+    GetSurfaceManager()->UnregisterBeginFrameSource(
+        data->gpu_vsync_begin_frame_source.get());
+  }
   per_compositor_data_.erase(it);
   if (per_compositor_data_.empty()) {
     // Destroying the GLHelper may cause some async actions to be cancelled,
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc
index cc419a3..1eaff27 100644
--- a/content/browser/devtools/protocol/input_handler.cc
+++ b/content/browser/devtools/protocol/input_handler.cc
@@ -12,6 +12,7 @@
 #include "base/trace_event/trace_event.h"
 #include "cc/output/compositor_frame_metadata.h"
 #include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/protocol/native_input_event_builder.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/common/input/synthetic_pinch_gesture_params.h"
@@ -298,7 +299,7 @@
                         auto_repeat.fromMaybe(false),
                         is_keypad.fromMaybe(false)),
       GetEventTimeTicks(std::move(timestamp)));
-  event.skip_in_browser = true;
+
   if (!SetKeyboardEventText(event.text, std::move(text))) {
     callback->sendFailure(Response::InvalidParams("Invalid 'text' parameter"));
     return;
@@ -331,7 +332,7 @@
     callback->sendFailure(Response::InternalError());
     return;
   }
-
+  event.os_event = NativeInputEventBuilder::CreateEvent(event);
   host_->GetRenderWidgetHost()->Focus();
   input_queued_ = false;
   pending_key_callbacks_.push_back(std::move(callback));
diff --git a/content/browser/devtools/protocol/native_input_event_builder.h b/content/browser/devtools/protocol/native_input_event_builder.h
new file mode 100644
index 0000000..e766e037
--- /dev/null
+++ b/content/browser/devtools/protocol/native_input_event_builder.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_NATIVE_INPUT_EVENT_BUILDER_H_
+#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_NATIVE_INPUT_EVENT_BUILDER_H_
+
+#include "content/public/browser/native_web_keyboard_event.h"
+
+namespace content {
+namespace protocol {
+
+class NativeInputEventBuilder {
+ public:
+#if defined(OS_MACOSX)
+  // This returned object has a retain count of 1.
+  static gfx::NativeEvent CreateEvent(const NativeWebKeyboardEvent& event);
+#else
+  // We only need this for Macs because they require an OS event to process
+  // some keyboard events in browser (see: crbug.com/667387).
+  static gfx::NativeEvent CreateEvent(const NativeWebKeyboardEvent& event) {
+    return nullptr;
+  }
+#endif
+};
+
+}  // namespace protocol
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_NATIVE_INPUT_EVENT_BUILDER_H_
diff --git a/content/browser/devtools/protocol/native_input_event_builder_mac.mm b/content/browser/devtools/protocol/native_input_event_builder_mac.mm
new file mode 100644
index 0000000..601ec19
--- /dev/null
+++ b/content/browser/devtools/protocol/native_input_event_builder_mac.mm
@@ -0,0 +1,49 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <Cocoa/Cocoa.h>
+#include "base/strings/sys_string_conversions.h"
+#include "content/browser/devtools/protocol/native_input_event_builder.h"
+#include "third_party/WebKit/public/platform/WebInputEvent.h"
+
+namespace content {
+namespace protocol {
+
+// Mac requires a native event to emulate key events. This method gives
+// only crude capabilities (see: crbug.com/667387).
+// The returned object has a retain count of 1.
+gfx::NativeEvent NativeInputEventBuilder::CreateEvent(
+    const NativeWebKeyboardEvent& event) {
+  NSEventType type = NSKeyUp;
+  if (event.GetType() == blink::WebInputEvent::kRawKeyDown ||
+      event.GetType() == blink::WebInputEvent::kKeyDown)
+    type = NSKeyDown;
+  const blink::WebUChar* textStartAddr = &event.text[0];
+  const int textLength =
+      std::find(textStartAddr,
+                textStartAddr + NativeWebKeyboardEvent::kTextLengthCap, '\0') -
+      textStartAddr;
+  NSString* character =
+      base::SysUTF16ToNSString(base::string16(textStartAddr, textLength));
+  int modifiers = event.GetModifiers();
+  NSUInteger flags =
+      (modifiers & blink::WebInputEvent::kShiftKey ? NSShiftKeyMask : 0) |
+      (modifiers & blink::WebInputEvent::kControlKey ? NSControlKeyMask : 0) |
+      (modifiers & blink::WebInputEvent::kAltKey ? NSAlternateKeyMask : 0) |
+      (modifiers & blink::WebInputEvent::kMetaKey ? NSCommandKeyMask : 0);
+
+  return [[NSEvent keyEventWithType:type
+                           location:NSZeroPoint
+                      modifierFlags:flags
+                          timestamp:0
+                       windowNumber:0
+                            context:nil
+                         characters:character
+        charactersIgnoringModifiers:character
+                          isARepeat:NO
+                            keyCode:event.native_key_code] retain];
+};
+
+}  // namespace protocol
+}  // namespace content
diff --git a/content/browser/plugin_private_storage_helper.cc b/content/browser/plugin_private_storage_helper.cc
index c6d19ac..2b25d828 100644
--- a/content/browser/plugin_private_storage_helper.cc
+++ b/content/browser/plugin_private_storage_helper.cc
@@ -43,7 +43,7 @@
 }
 
 // Helper for checking the plugin private data for a specified origin and
-// plugin for the existance of any file that matches the time range specified.
+// plugin for the existence of any file that matches the time range specified.
 // All of the operations in this class are done on the IO thread.
 //
 // This class keeps track of outstanding async requests it generates, and does
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 0fe80c4..945fa74 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -563,6 +563,10 @@
     host_->ReleaseCompositorFrameSink();
     has_compositor_frame_sink_ = false;
     pending_frames_ = 0;
+    if (display_) {
+      GetSurfaceManager()->UnregisterBeginFrameSource(
+          root_window_->GetBeginFrameSource());
+    }
     display_.reset();
   } else {
     host_->SetVisible(true);
@@ -775,14 +779,14 @@
   cc::SurfaceManager* manager = GetSurfaceManager();
   auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
   std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
-      task_runner, display_output_surface->capabilities().max_frames_pending));
+      root_window_->GetBeginFrameSource(), task_runner,
+      display_output_surface->capabilities().max_frames_pending));
 
   display_.reset(new cc::Display(
       viz::HostSharedBitmapManager::current(),
       BrowserGpuMemoryBufferManager::current(),
       host_->GetSettings().renderer_settings, frame_sink_id_,
-      root_window_->GetBeginFrameSource(), std::move(display_output_surface),
-      std::move(scheduler),
+      std::move(display_output_surface), std::move(scheduler),
       base::MakeUnique<cc::TextureMailboxDeleter>(task_runner)));
 
   auto compositor_frame_sink =
@@ -797,6 +801,8 @@
 
   display_->SetVisible(true);
   display_->Resize(size_);
+  GetSurfaceManager()->RegisterBeginFrameSource(
+      root_window_->GetBeginFrameSource(), frame_sink_id_);
   host_->SetCompositorFrameSink(std::move(compositor_frame_sink));
 }
 
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc
index 84520b8..0453ecbb 100644
--- a/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -204,7 +204,7 @@
   // files. If the bindings file doesn't exist assume we're on such a bot and
   // pass.
   // TODO(sky): remove this conditional when isolates support copying from gen.
-  base::ThreadRestrictions::ScopedAllowIO allow_io_for_file_existance_check;
+  base::ThreadRestrictions::ScopedAllowIO allow_io_for_file_existence_check;
   const base::FilePath test_file_path(GetFilePathForJSResource(resource_path));
   if (base::PathExists(test_file_path))
     return true;
diff --git a/content/renderer/android/synchronous_compositor_frame_sink.cc b/content/renderer/android/synchronous_compositor_frame_sink.cc
index a5d7fb8..18fc97375 100644
--- a/content/renderer/android/synchronous_compositor_frame_sink.cc
+++ b/content/renderer/android/synchronous_compositor_frame_sink.cc
@@ -198,8 +198,7 @@
   // process so there is no reason for it to use a SharedBitmapManager.
   display_.reset(new cc::Display(
       shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
-      software_renderer_settings, kRootFrameSinkId,
-      nullptr /* begin_frame_source */, std::move(output_surface),
+      software_renderer_settings, kRootFrameSinkId, std::move(output_surface),
       nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */));
   display_->Initialize(&display_client_, surface_manager_.get());
   display_->SetVisible(true);
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc
index 0e2322d0..59a2882 100644
--- a/content/renderer/input/main_thread_event_queue.cc
+++ b/content/renderer/input/main_thread_event_queue.cc
@@ -218,6 +218,7 @@
       handle_raf_aligned_mouse_input_(
           allow_raf_aligned_input &&
           base::FeatureList::IsEnabled(features::kRafAlignedMouseInputEvents)),
+      needs_low_latency_(false),
       main_task_runner_(main_task_runner),
       renderer_scheduler_(renderer_scheduler),
       use_raf_fallback_timer_(true) {
@@ -506,9 +507,9 @@
   switch (event->event().GetType()) {
     case blink::WebInputEvent::kMouseMove:
     case blink::WebInputEvent::kMouseWheel:
-      return handle_raf_aligned_mouse_input_;
+      return handle_raf_aligned_mouse_input_ && !needs_low_latency_;
     case blink::WebInputEvent::kTouchMove:
-      return handle_raf_aligned_touch_input_;
+      return handle_raf_aligned_touch_input_ && !needs_low_latency_;
     default:
       return false;
   }
@@ -559,4 +560,8 @@
   client_ = nullptr;
 }
 
+void MainThreadEventQueue::SetNeedsLowLatency(bool low_latency) {
+  needs_low_latency_ = low_latency;
+}
+
 }  // namespace content
diff --git a/content/renderer/input/main_thread_event_queue.h b/content/renderer/input/main_thread_event_queue.h
index 3c337eb..3370e01a 100644
--- a/content/renderer/input/main_thread_event_queue.h
+++ b/content/renderer/input/main_thread_event_queue.h
@@ -95,6 +95,7 @@
   void QueueClosure(const base::Closure& closure);
 
   void ClearClient();
+  void SetNeedsLowLatency(bool low_latency);
 
  protected:
   friend class base::RefCountedThreadSafe<MainThreadEventQueue>;
@@ -135,6 +136,7 @@
   base::TimeDelta main_thread_responsiveness_threshold_;
   bool handle_raf_aligned_touch_input_;
   bool handle_raf_aligned_mouse_input_;
+  bool needs_low_latency_;
 
   // Contains data to be shared between main thread and compositor thread.
   struct SharedState {
diff --git a/content/renderer/input/main_thread_event_queue_unittest.cc b/content/renderer/input/main_thread_event_queue_unittest.cc
index d162ca0..3c5dbf30 100644
--- a/content/renderer/input/main_thread_event_queue_unittest.cc
+++ b/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -722,6 +722,73 @@
   EXPECT_EQ(0u, additional_acked_events_.size());
 }
 
+TEST_P(MainThreadEventQueueTest, LowLatency) {
+  SyntheticWebTouchEvent kEvents[2];
+  kEvents[0].PressPoint(10, 10);
+  kEvents[1].PressPoint(10, 10);
+  kEvents[1].MovePoint(0, 50, 50);
+
+  queue_->SetNeedsLowLatency(true);
+  EXPECT_FALSE(main_task_runner_->HasPendingTask());
+  EXPECT_EQ(0u, event_queue().size());
+
+  for (SyntheticWebTouchEvent& event : kEvents)
+    HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+
+  EXPECT_EQ(2u, event_queue().size());
+  EXPECT_TRUE(main_task_runner_->HasPendingTask());
+  EXPECT_FALSE(needs_main_frame_);
+  main_task_runner_->RunUntilIdle();
+  EXPECT_EQ(0u, event_queue().size());
+  EXPECT_FALSE(main_task_runner_->HasPendingTask());
+
+  WebMouseEvent mouse_move = SyntheticWebMouseEventBuilder::Build(
+      WebInputEvent::kMouseMove, 10, 10, 0);
+  WebMouseWheelEvent mouse_wheel =
+      SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false);
+
+  HandleEvent(mouse_move, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+  HandleEvent(mouse_wheel, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+
+  EXPECT_EQ(2u, event_queue().size());
+  EXPECT_TRUE(main_task_runner_->HasPendingTask());
+  EXPECT_FALSE(needs_main_frame_);
+  main_task_runner_->RunUntilIdle();
+  EXPECT_EQ(0u, event_queue().size());
+
+  // Now turn off low latency mode.
+  queue_->SetNeedsLowLatency(false);
+  for (SyntheticWebTouchEvent& event : kEvents)
+    HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+
+  EXPECT_EQ(2u, event_queue().size());
+  EXPECT_TRUE(main_task_runner_->HasPendingTask());
+  if ((raf_aligned_input_setting_ & kRafAlignedEnabledTouch) == 0) {
+    EXPECT_FALSE(needs_main_frame_);
+    main_task_runner_->RunUntilIdle();
+  } else {
+    EXPECT_TRUE(needs_main_frame_);
+    RunPendingTasksWithSimulatedRaf();
+  }
+  EXPECT_EQ(0u, event_queue().size());
+  EXPECT_FALSE(main_task_runner_->HasPendingTask());
+
+  HandleEvent(mouse_move, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+  HandleEvent(mouse_wheel, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
+
+  EXPECT_EQ(2u, event_queue().size());
+  if ((raf_aligned_input_setting_ & kRafAlignedEnabledMouse) == 0) {
+    EXPECT_TRUE(main_task_runner_->HasPendingTask());
+    EXPECT_FALSE(needs_main_frame_);
+    main_task_runner_->RunUntilIdle();
+  } else {
+    EXPECT_FALSE(main_task_runner_->HasPendingTask());
+    EXPECT_TRUE(needs_main_frame_);
+    RunPendingTasksWithSimulatedRaf();
+  }
+  EXPECT_EQ(0u, event_queue().size());
+}
+
 TEST_P(MainThreadEventQueueTest, BlockingTouchesDuringFling) {
   SyntheticWebTouchEvent kEvents;
   kEvents.PressPoint(10, 10);
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index cb06ebf..3611cee2 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -1672,12 +1672,18 @@
         blink::WebPluginContainer::kTouchEventRequestTypeNone);
     return;
   }
-  bool raw_touch = (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH) ||
-                   (input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH);
-  container_->RequestTouchEventType(
-      raw_touch
-          ? blink::WebPluginContainer::kTouchEventRequestTypeRaw
-          : blink::WebPluginContainer::kTouchEventRequestTypeSynthesizedMouse);
+  blink::WebPluginContainer::TouchEventRequestType request_type =
+      blink::WebPluginContainer::kTouchEventRequestTypeSynthesizedMouse;
+  if ((filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_COALESCED_TOUCH) ||
+      (input_event_mask_ & PP_INPUTEVENT_CLASS_COALESCED_TOUCH)) {
+    request_type =
+        blink::WebPluginContainer::kTouchEventRequestTypeRawLowLatency;
+  } else if ((filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH) ||
+             (input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH)) {
+    request_type = blink::WebPluginContainer::kTouchEventRequestTypeRaw;
+  }
+
+  container_->RequestTouchEventType(request_type);
 }
 
 void PepperPluginInstanceImpl::UpdateWheelEventRequest() {
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 0b676bf3..a05ca82 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -2265,6 +2265,11 @@
   Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers));
 }
 
+void RenderWidget::SetNeedsLowLatencyInput(bool needs_low_latency) {
+  if (input_event_queue_)
+    input_event_queue_->SetNeedsLowLatency(needs_low_latency);
+}
+
 void RenderWidget::SetTouchAction(cc::TouchAction touch_action) {
   // Ignore setTouchAction calls that result from synthetic touch events (eg.
   // when blink is emulating touch with mouse).
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 06552149..39261b6 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -640,6 +640,9 @@
   // Check whether the WebWidget has any touch event handlers registered.
   void HasTouchEventHandlers(bool has_handlers) override;
 
+  // Called to update whether low latency input mode is enabled or not.
+  void SetNeedsLowLatencyInput(bool) override;
+
   // Tell the browser about the actions permitted for a new touch point.
   void SetTouchAction(cc::TouchAction touch_action) override;
 
diff --git a/content/shell/test_runner/test_plugin.cc b/content/shell/test_runner/test_plugin.cc
index 30f59f03..905a92c9 100644
--- a/content/shell/test_runner/test_plugin.cc
+++ b/content/shell/test_runner/test_plugin.cc
@@ -103,6 +103,8 @@
     const blink::WebString& string) {
   if (string == blink::WebString::FromUTF8("raw"))
     return blink::WebPluginContainer::kTouchEventRequestTypeRaw;
+  if (string == blink::WebString::FromUTF8("raw-lowlatency"))
+    return blink::WebPluginContainer::kTouchEventRequestTypeRawLowLatency;
   if (string == blink::WebString::FromUTF8("synthetic"))
     return blink::WebPluginContainer::kTouchEventRequestTypeSynthesizedMouse;
   return blink::WebPluginContainer::kTouchEventRequestTypeNone;
diff --git a/content/test/webui_resource_browsertest.cc b/content/test/webui_resource_browsertest.cc
index 3731475..14ac100 100644
--- a/content/test/webui_resource_browsertest.cc
+++ b/content/test/webui_resource_browsertest.cc
@@ -27,7 +27,7 @@
   // Runs all test functions in |file|, waiting for them to complete.
   void RunTest(const base::FilePath& file) {
     {
-      base::ThreadRestrictions::ScopedAllowIO allow_io_for_file_existance_check;
+      base::ThreadRestrictions::ScopedAllowIO allow_io_for_file_existence_check;
       ASSERT_TRUE(PathExists(file));
     }
 
diff --git a/dbus/object_manager.h b/dbus/object_manager.h
index 842a1378..c17f1408 100644
--- a/dbus/object_manager.h
+++ b/dbus/object_manager.h
@@ -211,12 +211,12 @@
 
   // Returns a ObjectProxy pointer for the given |object_path|. Unlike
   // the equivalent method on Bus this will return NULL if the object
-  // manager has not been informed of that object's existance.
+  // manager has not been informed of that object's existence.
   ObjectProxy* GetObjectProxy(const ObjectPath& object_path);
 
   // Returns a PropertySet* pointer for the given |object_path| and
   // |interface_name|, or NULL if the object manager has not been informed of
-  // that object's existance or the interface's properties. The caller should
+  // that object's existence or the interface's properties. The caller should
   // cast the returned pointer to the appropriate type, e.g.:
   //   static_cast<Properties*>(GetProperties(object_path, my_interface));
   PropertySet* GetProperties(const ObjectPath& object_path,
diff --git a/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java b/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java
index aed6822..9be2ee1 100644
--- a/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java
+++ b/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java
@@ -84,9 +84,13 @@
             // Request updates on UI Thread replicating LocationProviderAndroid's behaviour.
             mLocationProviderApi.requestLocationUpdates(
                     mGoogleApiClient, mLocationRequest, this, ThreadUtils.getUiThreadLooper());
-        } catch (IllegalStateException e) {
-            // Happens "If this method is executed in a thread that has not called Looper.prepare()"
-            Log.e(TAG, "Unexpected exception " + e);
+        } catch (IllegalStateException | SecurityException e) {
+            // IllegalStateException is thrown "If this method is executed in a thread that has not
+            // called Looper.prepare()". SecurityException is thrown if there is no permission, see
+            // https://crbug.com/731271.
+            Log.e(TAG, " mLocationProviderApi.requestLocationUpdates() " + e);
+            LocationProviderAdapter.newErrorAvailable(
+                    "Failed to request location updates: " + e.toString());
             assert false;
         }
     }
diff --git a/docs/task_scheduler_migration.md b/docs/task_scheduler_migration.md
index c5afe28..971903b 100644
--- a/docs/task_scheduler_migration.md
+++ b/docs/task_scheduler_migration.md
@@ -9,6 +9,10 @@
 Tasks in Chrome](threading_and_tasks.md). This page will go into more details
 about how to migrate callers of existing APIs to TaskScheduler.
 
+The SequencedWorkerPools and BrowserThreads (not UI/IO) are already being
+redirected to TaskScheduler under the hood so it's now "merely" a matter of
+updating the actual call sites.
+
 Much of the migration has already been automated but the callers that remain
 require manual intervention from the OWNERS.
 
diff --git a/extensions/renderer/api_signature.cc b/extensions/renderer/api_signature.cc
index e15a53f8..b2eb02f 100644
--- a/extensions/renderer/api_signature.cc
+++ b/extensions/renderer/api_signature.cc
@@ -317,10 +317,13 @@
   // the arguments in the signature. This is very broken.
   if (HasCallback(signature_)) {
     CHECK(!arguments.empty());
-    if (arguments[size - 1]->IsFunction()) {
-      callback = arguments[size - 1].As<v8::Function>();
-      --size;
-    }
+    v8::Local<v8::Value> value = arguments.back();
+    --size;
+    // Bindings should ensure that the value here is appropriate, but see the
+    // comment above for limitations.
+    DCHECK(value->IsFunction() || value->IsUndefined() || value->IsNull());
+    if (value->IsFunction())
+      callback = value.As<v8::Function>();
   }
 
   auto json = base::MakeUnique<base::ListValue>();
diff --git a/extensions/renderer/api_signature_unittest.cc b/extensions/renderer/api_signature_unittest.cc
index e62cfaa4..34ac719 100644
--- a/extensions/renderer/api_signature_unittest.cc
+++ b/extensions/renderer/api_signature_unittest.cc
@@ -66,6 +66,15 @@
   return base::MakeUnique<APISignature>(std::move(specs));
 }
 
+std::unique_ptr<APISignature> IntAndOptionalCallback() {
+  SpecVector specs;
+  specs.push_back(ArgumentSpecBuilder(ArgumentType::INTEGER, "int").Build());
+  specs.push_back(ArgumentSpecBuilder(ArgumentType::FUNCTION, "callback")
+                      .MakeOptional()
+                      .Build());
+  return base::MakeUnique<APISignature>(std::move(specs));
+}
+
 std::unique_ptr<APISignature> OptionalIntAndCallback() {
   SpecVector specs;
   specs.push_back(
@@ -341,4 +350,62 @@
   EXPECT_EQ("refEnum enum", RefEnum()->GetExpectedSignature());
 }
 
+TEST_F(APISignatureTest, ParseIgnoringSchema) {
+  v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = MainContext();
+
+  auto string_to_v8_vector = [context](base::StringPiece args) {
+    v8::Local<v8::Value> v8_args = V8ValueFromScriptSource(context, args);
+    EXPECT_FALSE(v8_args.IsEmpty());
+    EXPECT_TRUE(v8_args->IsArray());
+    std::vector<v8::Local<v8::Value>> vector_args;
+    EXPECT_TRUE(
+        gin::ConvertFromV8(context->GetIsolate(), v8_args, &vector_args));
+    return vector_args;
+  };
+
+  {
+    // Test with providing an optional callback.
+    auto signature = IntAndOptionalCallback();
+    std::vector<v8::Local<v8::Value>> v8_args =
+        string_to_v8_vector("[1, function() {}]");
+    v8::Local<v8::Function> callback;
+    std::unique_ptr<base::ListValue> parsed;
+    EXPECT_TRUE(signature->ConvertArgumentsIgnoringSchema(context, v8_args,
+                                                          &parsed, &callback));
+    ASSERT_TRUE(parsed);
+    EXPECT_EQ("[1]", ValueToString(*parsed));
+    EXPECT_FALSE(callback.IsEmpty());
+  }
+
+  {
+    // Test with omitting the optional callback.
+    auto signature = IntAndOptionalCallback();
+    std::vector<v8::Local<v8::Value>> v8_args =
+        string_to_v8_vector("[1, null]");
+    v8::Local<v8::Function> callback;
+    std::unique_ptr<base::ListValue> parsed;
+    EXPECT_TRUE(signature->ConvertArgumentsIgnoringSchema(context, v8_args,
+                                                          &parsed, &callback));
+    ASSERT_TRUE(parsed);
+    EXPECT_EQ("[1]", ValueToString(*parsed));
+    EXPECT_TRUE(callback.IsEmpty());
+  }
+
+  {
+    // Test with providing something completely different than the spec, which
+    // is (unfortunately) allowed and used.
+    auto signature = OneString();
+    std::vector<v8::Local<v8::Value>> v8_args =
+        string_to_v8_vector("[{not: 'a string'}]");
+    v8::Local<v8::Function> callback;
+    std::unique_ptr<base::ListValue> parsed;
+    EXPECT_TRUE(signature->ConvertArgumentsIgnoringSchema(context, v8_args,
+                                                          &parsed, &callback));
+    ASSERT_TRUE(parsed);
+    EXPECT_EQ(R"([{"not":"a string"}])", ValueToString(*parsed));
+    EXPECT_TRUE(callback.IsEmpty());
+  }
+}
+
 }  // namespace extensions
diff --git a/extensions/renderer/resources/context_menus_handlers.js b/extensions/renderer/resources/context_menus_handlers.js
index eed54796..0e718c4f 100644
--- a/extensions/renderer/resources/context_menus_handlers.js
+++ b/extensions/renderer/resources/context_menus_handlers.js
@@ -187,7 +187,7 @@
         'chromeWebViewInternal.contextMenusRemoveAll' :
         'contextMenus.removeAll';
     sendRequest(name, $Array.from(arguments),
-                this.definition.parameters, optArgs);
+                bindingUtil ? undefined : this.definition.parameters, optArgs);
   };
 
   return {
diff --git a/extensions/shell/installer/BUILD.gn b/extensions/shell/installer/BUILD.gn
deleted file mode 100644
index 5d8aa82..0000000
--- a/extensions/shell/installer/BUILD.gn
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/ui.gni")
-import("//build/util/process_version.gni")
-import("//extensions/features/features.gni")
-
-assert(enable_extensions)
-
-declare_args() {
-  enable_app_shell_installer =
-      is_desktop_linux && is_chrome_branded && current_cpu == "x64"
-}
-
-# Meta-target that forwards to the installer of the correct type (if any).
-group("installer") {
-  # See the "app_shell_lib" definition for why testonly is needed.
-  testonly = true
-  if (enable_app_shell_installer) {
-    deps = [
-      "//extensions/shell/installer/linux",
-    ]
-  }
-}
diff --git a/extensions/shell/installer/linux/BUILD.gn b/extensions/shell/installer/linux/BUILD.gn
deleted file mode 100644
index 8883c20..0000000
--- a/extensions/shell/installer/linux/BUILD.gn
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO(michaelpg): Dedupe with Chrome installer.
-
-import("//build/config/chrome_build.gni")
-import("//build/config/features.gni")
-import("//build/config/sanitizers/sanitizers.gni")
-import("//build/config/sysroot.gni")
-import("//build/util/version.gni")
-import("//chrome/process_version_rc_template.gni")  # For branding_file_path.
-
-assert(is_desktop_linux)
-assert(current_cpu == "x64")
-
-# The packages list the exact versions of each library used. The versions used
-# on the bots are likely different than those on your workstation, so you'll
-# get a stream of errors like:
-#   < libasound2 (>= 1.0.23)
-#   ---
-#   > libasound2 (>= 1.0.16)
-#
-# To avoid these warnings for testing purposes, do:
-#
-#   export IGNORE_DEPS_CHANGES=1
-#
-# before you build.
-group("linux") {
-  # See the "app_shell_lib" definition for why testonly is needed.
-  testonly = true
-  deps = [
-    # TODO(michaelpg): Add beta/stable once we verify the unstable installer is
-    # building and installing properly.
-    ":unstable",
-  ]
-}
-
-branding_dir = "//chrome/app/theme/$branding_path_component"
-
-copy("common_packaging_files") {
-  visibility = [ ":*" ]
-  sources = [
-    "//chrome/installer/linux/common/apt.include",
-    "//chrome/installer/linux/common/repo.cron",
-    "//chrome/installer/linux/common/symlinks.include",
-    "//chrome/installer/linux/common/variables.include",
-    "/usr/bin/eu-strip",
-    "common/installer.include",
-    "common/wrapper",
-  ]
-
-  if (is_chrome_branded) {
-    sources += [ "common/google-app-shell/google-app-shell.info" ]
-  } else {
-    sources += [ "common/chromium-app-shell/chromium-app-shell.info" ]
-  }
-
-  outputs = [
-    "$root_out_dir/app_shell_installer/common/{{source_file_part}}",
-  ]
-}
-
-copy("deb_packaging_files") {
-  visibility = [ ":*" ]
-  sources = [
-    "//chrome/installer/linux/debian/changelog.template",
-    "//chrome/installer/linux/debian/control.template",
-    "debian/build.sh",
-    "debian/expected_deps_x64_jessie",
-    "debian/postinst",
-    "debian/postrm",
-  ]
-  outputs = [
-    "$root_out_dir/app_shell_installer/debian/{{source_file_part}}",
-  ]
-}
-
-copy("theme_files") {
-  visibility = [ ":*" ]
-  sources = [
-    "$branding_dir/BRANDING",
-  ]
-  outputs = [
-    "$root_out_dir/app_shell_installer/theme/{{source_file_part}}",
-  ]
-}
-
-process_version("save_build_info") {
-  # Just output the default version info variables (no template).
-  process_only = true
-  sources = [
-    "//build/util/LASTCHANGE",
-    "//chrome/VERSION",
-    branding_file_path,
-  ]
-  output = "$root_out_dir/app_shell_installer/version.txt"
-}
-
-# Dependencies for all Linux installer targets.
-group("installer_deps") {
-  testonly = true
-
-  # Though many of these things appear in data_deps further down the
-  # dependency chain, they must appear here as public_deps so that they can
-  # be listed as inputs to the actions that depend on ":installer_deps"
-  # and are guaranteed to have been built before those actions run.
-
-  public_deps = [
-    ":common_packaging_files",
-    ":deb_packaging_files",
-    ":save_build_info",
-    ":theme_files",
-    "//extensions:shell_and_test_pak",
-    "//extensions/shell:app_shell",
-  ]
-  if (enable_nacl) {
-    public_deps += [
-      "//components/nacl/loader:nacl_helper",
-
-      # These are data_deps of nacl_helper, but that is not enough,
-      # as explained above.
-      "//native_client/src/trusted/service_runtime/linux:bootstrap",
-      "//ppapi/native_client:irt",
-    ]
-  }
-  if (use_custom_libcxx) {
-    public_deps += [ "//buildtools/third_party/libc++" ]
-  }
-}
-
-# Creates .deb installer package.
-#
-# channel:
-#   Name of the channel.
-template("linux_package") {
-  testonly = true
-  assert(defined(invoker.channel))
-  channel = invoker.channel
-
-  packaging_files_binaries = [
-    # TODO(mmoss) Any convenient way to get all the relevant build
-    # files? (e.g. all locales, resources, etc.)
-    "$root_out_dir/app_shell",
-    "$root_out_dir/extensions_shell_and_test.pak",
-  ]
-
-  if (enable_nacl) {
-    packaging_files_binaries += [
-      "$root_out_dir/nacl_helper",
-      "$root_out_dir/nacl_helper_bootstrap",
-      "$root_out_dir/nacl_irt_x86_64.nexe",
-    ]
-  }
-
-  if (use_custom_libcxx) {
-    packaging_files_binaries += [ "$root_out_dir/libc++.so" ]
-  }
-
-  deb_target_name = "${target_name}_deb"
-  action(deb_target_name) {
-    visibility = [ ":*" ]
-    script = "//chrome/installer/linux/flock_make_package.py"
-    deb_arch = "amd64"
-
-    inputs = packaging_files_binaries
-    outputs = [
-      "$root_out_dir/google-app-shell-${channel}_${chrome_version_full}-1_${deb_arch}.deb",
-    ]
-
-    args = [
-      rebase_path("$root_out_dir/linux_package.lock", root_build_dir),
-      rebase_path("$root_out_dir/app_shell_installer/debian/build.sh",
-                  root_build_dir),
-      "-o",
-      rebase_path(root_out_dir, root_build_dir),
-      "-b",
-      rebase_path(root_out_dir, root_build_dir),
-      "-a",
-      current_cpu,
-      "-c",
-      invoker.channel,
-      "-d",
-      branding_path_component,
-      "-s",
-      rebase_path(sysroot),
-    ]
-    deps = [
-      ":installer_deps",
-    ]
-  }
-
-  group(target_name) {
-    deps = [
-      ":$deb_target_name",
-    ]
-  }
-}
-
-# Standard packages.
-linux_package("unstable") {
-  channel = "unstable"
-}
-linux_package("stable") {
-  channel = "stable"
-}
-linux_package("beta") {
-  channel = "beta"
-}
-
-# Other packages that we support that aren't included in the default "linux"
-# target.
-linux_package("trunk") {
-  channel = "trunk"
-}
-if (is_asan) {
-  linux_package("asan") {
-    channel = "asan"
-  }
-}
diff --git a/extensions/shell/installer/linux/common/chromium-app-shell/chromium-app-shell.info b/extensions/shell/installer/linux/common/chromium-app-shell/chromium-app-shell.info
deleted file mode 100644
index ee88042..0000000
--- a/extensions/shell/installer/linux/common/chromium-app-shell/chromium-app-shell.info
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This file provides common configuration information for building
-# chromium-app-shell for various platforms.
-
-# Base name of the package.
-PACKAGE="chromium-app-shell"
-
-# Filename of the main executable (for generating launcher scripts, etc.)
-PROGNAME=app_shell
-
-# Base directory for package installation.
-INSTALLDIR=/opt/chromium.org/app-shell
-
-# Display string for desktop menu/icon.
-MENUNAME="Chromium App Shell"
-
-# Brief package description.
-SHORTDESC="The app shell from Chromium.org"
-
-# Detailed package description.
-FULLDESC="The app shell from Chromium.org"
-
-# Package maintainer information.
-# TODO(mmoss) Setup a mailbox for this address
-MAINTNAME="Chromium Linux Team"
-MAINTMAIL="chromium-linux-packager@chromium.org"
-PRODUCTURL="http://www.chromium.org/"
diff --git a/extensions/shell/installer/linux/common/google-app-shell/google-app-shell.info b/extensions/shell/installer/linux/common/google-app-shell/google-app-shell.info
deleted file mode 100644
index 4086733..0000000
--- a/extensions/shell/installer/linux/common/google-app-shell/google-app-shell.info
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This file provides common configuration information for building
-# app-shell packages for various platforms.
-
-# Base name of the package.
-PACKAGE="google-app-shell"
-
-# Filename of the main executable (for generating launcher scripts, etc.)
-PROGNAME=app_shell
-
-# Base directory for package installation.
-INSTALLDIR=/opt/google/app-shell
-
-# Display string for desktop menu/icon.
-MENUNAME="App Shell"
-
-# Brief package description.
-SHORTDESC="The app shell from Google"
-
-# Detailed package description.
-FULLDESC="The app shell from Google"
-
-# Package maintainer information.
-# TODO(mmoss) Setup a mailbox for this address
-MAINTNAME="Chrome Linux Team"
-MAINTMAIL="chromium-dev@chromium.org"
-PRODUCTURL="https://chrome.google.com/"
diff --git a/extensions/shell/installer/linux/common/installer.include b/extensions/shell/installer/linux/common/installer.include
deleted file mode 100644
index 521916f..0000000
--- a/extensions/shell/installer/linux/common/installer.include
+++ /dev/null
@@ -1,193 +0,0 @@
-# TODO(michaelpg): Dedupe common functionality with the Chrome installer.
-
-# Recursively replace @@include@@ template variables with the referenced file,
-# and write the resulting text to stdout.
-process_template_includes() {
-  INCSTACK+="$1->"
-  # Includes are relative to the file that does the include.
-  INCDIR=$(dirname $1)
-  # Clear IFS so 'read' doesn't trim whitespace
-  local OLDIFS="$IFS"
-  IFS=''
-  while read -r LINE
-  do
-    INCLINE=$(sed -e '/^[[:space:]]*@@include@@/!d' <<<$LINE)
-    if [ -n "$INCLINE" ]; then
-      INCFILE=$(echo $INCLINE | sed -e "s#@@include@@\(.*\)#\1#")
-      # Simple filename match to detect cyclic includes.
-      CYCLE=$(sed -e "\#$INCFILE#"'!d' <<<$INCSTACK)
-      if [ "$CYCLE" ]; then
-        echo "ERROR: Possible cyclic include detected." 1>&2
-        echo "$INCSTACK$INCFILE" 1>&2
-        exit 1
-      fi
-      if [ ! -r "$INCDIR/$INCFILE" ]; then
-        echo "ERROR: Couldn't read include file: $INCDIR/$INCFILE" 1>&2
-        exit 1
-      fi
-      process_template_includes "$INCDIR/$INCFILE"
-    else
-      echo "$LINE"
-    fi
-  done < "$1"
-  IFS="$OLDIFS"
-  INCSTACK=${INCSTACK%"$1->"}
-}
-
-# Replace template variables (@@VARNAME@@) in the given template file. If a
-# second argument is given, save the processed text to that filename, otherwise
-# modify the template file in place.
-process_template() (
-  # Don't worry if some of these substitution variables aren't set.
-  # Note that this function is run in a sub-shell so we don't leak this
-  # setting, since we still want unbound variables to be an error elsewhere.
-  set +u
-
-  local TMPLIN="$1"
-  if [ -z "$2" ]; then
-    local TMPLOUT="$TMPLIN"
-  else
-    local TMPLOUT="$2"
-  fi
-  # Process includes first so included text also gets substitutions.
-  TMPLINCL="$(process_template_includes "$TMPLIN")"
-  sed \
-    -e "s#@@PACKAGE@@#${PACKAGE}#g" \
-    -e "s#@@PACKAGE_FILENAME@@#${PACKAGE_FILENAME}#g" \
-    -e "s#@@PROGNAME@@#${PROGNAME}#g" \
-    -e "s#@@CHANNEL@@#${CHANNEL}#g" \
-    -e "s#@@COMPANY_FULLNAME@@#${COMPANY_FULLNAME}#g" \
-    -e "s#@@VERSION@@#${VERSION}#g" \
-    -e "s#@@PACKAGE_RELEASE@@#${PACKAGE_RELEASE}#g" \
-    -e "s#@@VERSIONFULL@@#${VERSIONFULL}#g" \
-    -e "s#@@INSTALLDIR@@#${INSTALLDIR}#g" \
-    -e "s#@@BUILDDIR@@#${BUILDDIR}#g" \
-    -e "s#@@STAGEDIR@@#${STAGEDIR}#g" \
-    -e "s#@@SCRIPTDIR@@#${SCRIPTDIR}#g" \
-    -e "s#@@MENUNAME@@#${MENUNAME}#g" \
-    -e "s#@@PRODUCTURL@@#${PRODUCTURL}#g" \
-    -e "s#@@PREDEPENDS@@#${PREDEPENDS}#g" \
-    -e "s#@@DEPENDS@@#${DEPENDS}#g" \
-    -e "s#@@PROVIDES@@#${PROVIDES}#g" \
-    -e "s#@@REPLACES@@#${REPLACES}#g" \
-    -e "s#@@CONFLICTS@@#${CONFLICTS}#g" \
-    -e "s#@@ARCHITECTURE@@#${ARCHITECTURE}#g" \
-    -e "s#@@MAINTNAME@@#${MAINTNAME}#g" \
-    -e "s#@@MAINTMAIL@@#${MAINTMAIL}#g" \
-    -e "s#@@REPOCONFIG@@#${REPOCONFIG}#g" \
-    -e "s#@@REPOCONFIGREGEX@@#${REPOCONFIGREGEX}#g" \
-    -e "s#@@SHORTDESC@@#${SHORTDESC}#g" \
-    -e "s#@@FULLDESC@@#${FULLDESC}#g" \
-    -e "s#@@USR_BIN_SYMLINK_NAME@@#${USR_BIN_SYMLINK_NAME:-}#g" \
-    > "$TMPLOUT" <<< "$TMPLINCL"
-)
-
-# Setup the installation directory hierachy in the package staging area.
-prep_staging_common() {
-  install -m 755 -d "${STAGEDIR}/${INSTALLDIR}" \
-    "${STAGEDIR}/usr/bin"
-}
-
-get_version_info() {
-  source "${BUILDDIR}/app_shell_installer/version.txt"
-  VERSION="${MAJOR}.${MINOR}.${BUILD}.${PATCH}"
-  # TODO(phajdan.jr): Provide a mechanism to pass a different package
-  # release number if needed. The meaning of it is to bump it for
-  # packaging-only changes while the underlying software has the same version.
-  # This corresponds to the Release field in RPM spec files and debian_revision
-  # component of the Version field for DEB control file.
-  # Generally with Chrome's fast release cycle it'd be more hassle to try
-  # to bump this number between releases.
-  PACKAGE_RELEASE="1"
-}
-
-stage_install_common() {
-  echo "Staging common install files in '${STAGEDIR}'..."
-
-  # TODO(mmoss) This assumes we built the static binaries. To support shared
-  # builds, we probably want an install target in scons so it can give us all
-  # the right files. See also:
-  # http://code.google.com/p/chromium/issues/detail?id=4451
-  #
-  # app
-  # We need to add the debug link so gdb knows to look for the symbols.
-  DEBUGFILE="${BUILDDIR}/${PROGNAME}.debug"
-  STRIPPEDFILE="${BUILDDIR}/${PROGNAME}.stripped"
-  "${BUILDDIR}/app_shell_installer/common/eu-strip" -o "${STRIPPEDFILE}" -f "${DEBUGFILE}" "${BUILDDIR}/${PROGNAME}"
-  install -m 755 "${STRIPPEDFILE}" "${STAGEDIR}/${INSTALLDIR}/${PROGNAME}"
-  rm "${DEBUGFILE}" "${STRIPPEDFILE}"
-
-  # resources
-  install -m 644 \
-    "${BUILDDIR}/extensions_shell_and_test.pak" \
-    "${STAGEDIR}/${INSTALLDIR}/"
-
-
-  # ICU data file; only necessary when icu_use_data_file_flag is set to 1
-  # in build/common.gypi.
-  install -m 644 "${BUILDDIR}/icudtl.dat" "${STAGEDIR}/${INSTALLDIR}/"
-
-  # V8 snapshot files; only necessary when v8_use_external_startup_data is
-  # set to 1 in build/common.gypi.
-  if [ -f "${BUILDDIR}/natives_blob.bin" ]; then
-    install -m 644 "${BUILDDIR}/natives_blob.bin" "${STAGEDIR}/${INSTALLDIR}/"
-    install -m 644 "${BUILDDIR}/snapshot_blob.bin" "${STAGEDIR}/${INSTALLDIR}/"
-  fi
-
-  # ANGLE
-  if [ "${CHANNEL}" != "stable" ]; then
-    install -m 644 "${BUILDDIR}/libGLESv2.so" "${STAGEDIR}/${INSTALLDIR}/"
-    install -m 644 "${BUILDDIR}/libEGL.so" "${STAGEDIR}/${INSTALLDIR}/"
-  fi
-
-  # SwiftShader
-  if [ -f "${BUILDDIR}/swiftshader/libEGL.so" ]; then
-    install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/swiftshader/"
-    install -m 644 "${BUILDDIR}/swiftshader/libEGL.so" "${STAGEDIR}/${INSTALLDIR}/swiftshader/"
-    install -m 644 "${BUILDDIR}/swiftshader/libGLESv2.so" "${STAGEDIR}/${INSTALLDIR}/swiftshader/"
-  fi
-
-  # libc++
-  if [ -f "${BUILDDIR}/lib/libc++.so" ]; then
-    install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/lib/"
-
-    install -m 644 -s "${BUILDDIR}/lib/libc++.so" "${STAGEDIR}/${INSTALLDIR}/lib/"
-  fi
-
-
-  # nacl_helper and nacl_helper_bootstrap
-  # Don't use "-s" (strip) because this runs binutils "strip", which
-  # mangles the special ELF program headers of nacl_helper_bootstrap.
-  # Explicitly use eu-strip instead, because it doesn't have that problem.
-  for file in nacl_helper nacl_helper_bootstrap; do
-    buildfile="${BUILDDIR}/${file}"
-    if [ -f "${buildfile}" ]; then
-      strippedfile="${buildfile}.stripped"
-      debugfile="${buildfile}.debug"
-      "${BUILDDIR}/app_shell_installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}"
-      install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/${file}"
-    fi
-  done
-  # Don't use "-s" (strip) because this would use the Linux toolchain to
-  # strip the NaCl binary, which has the potential to break it.  It
-  # certainly resets the OSABI and ABIVERSION fields to non-NaCl values,
-  # although the NaCl IRT loader doesn't care about these fields.  In any
-  # case, the IRT binaries are already stripped by NaCl's build process.
-  for filename in ${BUILDDIR}/nacl_irt_*.nexe; do
-    # Re-check the filename in case globbing matched nothing.
-    if [ -f "$filename" ]; then
-      install -m 644 "$filename" "${STAGEDIR}/${INSTALLDIR}/`basename "$filename"`"
-    fi
-  done
-
-  # launcher script and symlink
-  process_template "${BUILDDIR}/app_shell_installer/common/wrapper" \
-    "${STAGEDIR}/${INSTALLDIR}/${PACKAGE}"
-  chmod 755 "${STAGEDIR}/${INSTALLDIR}/${PACKAGE}"
-  if [ ! -f "${STAGEDIR}/${INSTALLDIR}/app-shell" ]; then
-    ln -sn "${INSTALLDIR}/${PACKAGE}" \
-      "${STAGEDIR}/${INSTALLDIR}/app-shell"
-  fi
-  ln -snf "${INSTALLDIR}/${PACKAGE}" \
-    "${STAGEDIR}/usr/bin/${USR_BIN_SYMLINK_NAME}"
-}
diff --git a/extensions/shell/installer/linux/common/wrapper b/extensions/shell/installer/linux/common/wrapper
deleted file mode 100755
index 487e5225..0000000
--- a/extensions/shell/installer/linux/common/wrapper
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Let the wrapped binary know that it has been run through the wrapper.
-export APP_SHELL_WRAPPER="`readlink -f "$0"`"
-
-HERE="`dirname "$APP_SHELL_WRAPPER"`"
-
-# Always use our versions of ffmpeg libs.
-if [[ -n "$LD_LIBRARY_PATH" ]]; then
-  LD_LIBRARY_PATH="$HERE:$HERE/lib:$LD_LIBRARY_PATH"
-else
-  LD_LIBRARY_PATH="$HERE:$HERE/lib"
-fi
-export LD_LIBRARY_PATH
-
-export CHROME_VERSION_EXTRA="@@CHANNEL@@"
-
-# We don't want bug-buddy intercepting our crashes. http://crbug.com/24120
-export GNOME_DISABLE_CRASH_DIALOG=SET_BY_GOOGLE_CHROME
-
-# Sanitize std{in,out,err} because they'll be shared with untrusted child
-# processes (http://crbug.com/376567).
-exec < /dev/null
-exec > >(exec cat)
-exec 2> >(exec cat >&2)
-
-# Note: exec -a below is a bashism.
-exec -a "$0" "$HERE/@@PROGNAME@@" "$@"
diff --git a/extensions/shell/installer/linux/debian/build.sh b/extensions/shell/installer/linux/debian/build.sh
deleted file mode 100755
index 331d9ad4..0000000
--- a/extensions/shell/installer/linux/debian/build.sh
+++ /dev/null
@@ -1,351 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO(michaelpg): Dedupe common functionality with the Chrome installer.
-
-# TODO(mmoss) This currently only works with official builds, since non-official
-# builds don't add the "${BUILDDIR}/app_shell_installer/" files needed for
-# packaging.
-
-set -e
-set -o pipefail
-if [ "$VERBOSE" ]; then
-  set -x
-fi
-set -u
-
-# Create the Debian changelog file needed by dpkg-gencontrol. This just adds a
-# placeholder change, indicating it is the result of an automatic build.
-# TODO(mmoss) Release packages should create something meaningful for a
-# changelog, but simply grabbing the actual 'svn log' is way too verbose. Do we
-# have any type of "significant/visible changes" log that we could use for this?
-gen_changelog() {
-  rm -f "${DEB_CHANGELOG}"
-  process_template "${SCRIPTDIR}/changelog.template" "${DEB_CHANGELOG}"
-  debchange -a --nomultimaint -m --changelog "${DEB_CHANGELOG}" \
-    "Release Notes: ${RELEASENOTES}"
-  GZLOG="${STAGEDIR}/usr/share/doc/${PACKAGE}-${CHANNEL}/changelog.gz"
-  mkdir -p "$(dirname "${GZLOG}")"
-  gzip -9 -c "${DEB_CHANGELOG}" > "${GZLOG}"
-  chmod 644 "${GZLOG}"
-}
-
-# Create the Debian control file needed by dpkg-deb.
-gen_control() {
-  dpkg-gencontrol -v"${VERSIONFULL}" -c"${DEB_CONTROL}" -l"${DEB_CHANGELOG}" \
-  -f"${DEB_FILES}" -p"${PACKAGE}-${CHANNEL}" -P"${STAGEDIR}" \
-  -O > "${STAGEDIR}/DEBIAN/control"
-  rm -f "${DEB_CONTROL}"
-}
-
-# Setup the installation directory hierachy in the package staging area.
-prep_staging_debian() {
-  prep_staging_common
-  install -m 755 -d "${STAGEDIR}/DEBIAN" \
-    "${STAGEDIR}/etc/cron.daily" \
-    "${STAGEDIR}/usr/share/doc/${USR_BIN_SYMLINK_NAME}"
-}
-
-# Put the package contents in the staging area.
-stage_install_debian() {
-  # Always use a different name for /usr/bin symlink depending on channel to
-  # avoid file collisions.
-  local USR_BIN_SYMLINK_NAME="${PACKAGE}-${CHANNEL}"
-
-  if [ "$CHANNEL" != "stable" ]; then
-    # Avoid file collisions between channels.
-    local INSTALLDIR="${INSTALLDIR}-${CHANNEL}"
-
-    local PACKAGE="${PACKAGE}-${CHANNEL}"
-  fi
-  prep_staging_debian
-  stage_install_common
-  echo "Staging Debian install files in '${STAGEDIR}'..."
-  install -m 755 -d "${STAGEDIR}/${INSTALLDIR}/cron"
-  process_template "${BUILDDIR}/app_shell_installer/common/repo.cron" \
-      "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}"
-  chmod 755 "${STAGEDIR}/${INSTALLDIR}/cron/${PACKAGE}"
-  pushd "${STAGEDIR}/etc/cron.daily/"
-  ln -snf "${INSTALLDIR}/cron/${PACKAGE}" "${PACKAGE}"
-  popd
-  process_template "${BUILDDIR}/app_shell_installer/debian/postinst" \
-    "${STAGEDIR}/DEBIAN/postinst"
-  chmod 755 "${STAGEDIR}/DEBIAN/postinst"
-  process_template "${BUILDDIR}/app_shell_installer/debian/postrm" \
-    "${STAGEDIR}/DEBIAN/postrm"
-  chmod 755 "${STAGEDIR}/DEBIAN/postrm"
-}
-
-# Actually generate the package file.
-do_package() {
-  echo "Packaging ${ARCHITECTURE}..."
-  PREDEPENDS="$COMMON_PREDEPS"
-  DEPENDS="${COMMON_DEPS}"
-  REPLACES=""
-  CONFLICTS=""
-  PROVIDES=""
-  gen_changelog
-  process_template "${SCRIPTDIR}/control.template" "${DEB_CONTROL}"
-  export DEB_HOST_ARCH="${ARCHITECTURE}"
-  if [ -f "${DEB_CONTROL}" ]; then
-    gen_control
-  fi
-  fakeroot dpkg-deb -Zxz -z9 -b "${STAGEDIR}" .
-}
-
-verify_package() {
-  DEPENDS="${COMMON_DEPS}"  # This needs to match do_package() above.
-  echo ${DEPENDS} | sed 's/, /\n/g' | LANG=C sort > expected_deb_depends
-  dpkg -I "${PACKAGE}-${CHANNEL}_${VERSIONFULL}_${ARCHITECTURE}.deb" | \
-      grep '^ Depends: ' | sed 's/^ Depends: //' | sed 's/, /\n/g' | \
-      LANG=C sort > actual_deb_depends
-  BAD_DIFF=0
-  diff -u expected_deb_depends actual_deb_depends || BAD_DIFF=1
-  if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then
-    echo
-    echo "ERROR: bad dpkg dependencies!"
-    echo
-    exit $BAD_DIFF
-  fi
-}
-
-# Remove temporary files and unwanted packaging output.
-cleanup() {
-  echo "Cleaning..."
-  rm -rf "${STAGEDIR}"
-  rm -rf "${TMPFILEDIR}"
-}
-
-usage() {
-  echo "usage: $(basename $0) [-c channel] [-a target_arch] [-o 'dir'] "
-  echo "                      [-b 'dir'] -d branding"
-  echo "-c channel the package channel (trunk, asan, unstable, beta, stable)"
-  echo "-a arch    package architecture (ia32 or x64)"
-  echo "-o dir     package output directory [${OUTPUTDIR}]"
-  echo "-b dir     build input directory    [${BUILDDIR}]"
-  echo "-d brand   either chromium or google_chrome"
-  echo "-s dir     /path/to/sysroot"
-  echo "-h         this help message"
-}
-
-# Check that the channel name is one of the allowable ones.
-verify_channel() {
-  case $CHANNEL in
-    stable )
-      CHANNEL=stable
-      RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Stable%20updates"
-      ;;
-    unstable|dev|alpha )
-      CHANNEL=unstable
-      RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Dev%20updates"
-      ;;
-    testing|beta )
-      CHANNEL=beta
-      RELEASENOTES="http://googlechromereleases.blogspot.com/search/label/Beta%20updates"
-      ;;
-    trunk|asan )
-      # Setting this to empty will prevent it from updating any existing configs
-      # from release packages.
-      REPOCONFIG=""
-      RELEASENOTES="http://googlechromereleases.blogspot.com/"
-      ;;
-    * )
-      echo
-      echo "ERROR: '$CHANNEL' is not a valid channel type."
-      echo
-      exit 1
-      ;;
-  esac
-}
-
-process_opts() {
-  while getopts ":s:o:b:c:a:d:h" OPTNAME
-  do
-    case $OPTNAME in
-      o )
-        OUTPUTDIR=$(readlink -f "${OPTARG}")
-        mkdir -p "${OUTPUTDIR}"
-        ;;
-      b )
-        BUILDDIR=$(readlink -f "${OPTARG}")
-        ;;
-      c )
-        CHANNEL="$OPTARG"
-        ;;
-      a )
-        TARGETARCH="$OPTARG"
-        ;;
-      d )
-        BRANDING="$OPTARG"
-        ;;
-      s )
-        SYSROOT="$OPTARG"
-        ;;
-      h )
-        usage
-        exit 0
-        ;;
-      \: )
-        echo "'-$OPTARG' needs an argument."
-        usage
-        exit 1
-        ;;
-      * )
-        echo "invalid command-line option: $OPTARG"
-        usage
-        exit 1
-        ;;
-    esac
-  done
-}
-
-#=========
-# MAIN
-#=========
-
-SCRIPTDIR=$(readlink -f "$(dirname "$0")")
-OUTPUTDIR="${PWD}"
-STAGEDIR=$(mktemp -d -t deb.build.XXXXXX) || exit 1
-TMPFILEDIR=$(mktemp -d -t deb.tmp.XXXXXX) || exit 1
-DEB_CHANGELOG="${TMPFILEDIR}/changelog"
-DEB_FILES="${TMPFILEDIR}/files"
-DEB_CONTROL="${TMPFILEDIR}/control"
-CHANNEL="trunk"
-# Default target architecture to same as build host.
-if [ "$(uname -m)" = "x86_64" ]; then
-  TARGETARCH="x64"
-else
-  TARGETARCH="ia32"
-fi
-
-# call cleanup() on exit
-trap cleanup 0
-process_opts "$@"
-BUILDDIR=${BUILDDIR:=$(readlink -f "${SCRIPTDIR}/../../../../out/Release")}
-
-if [[ "$(basename ${SYSROOT})" = "debian_jessie_"*"-sysroot" ]]; then
-  TARGET_DISTRO="jessie"
-else
-  echo "Debian package can only be built using the jessie sysroot."
-  exit 1
-fi
-
-source ${BUILDDIR}/app_shell_installer/common/installer.include
-
-get_version_info
-VERSIONFULL="${VERSION}-${PACKAGE_RELEASE}"
-
-if [ "$BRANDING" = "google_chrome" ]; then
-  source "${BUILDDIR}/app_shell_installer/common/google-app-shell.info"
-else
-  source "${BUILDDIR}/app_shell_installer/common/chromium-app-shell.info"
-fi
-eval $(sed -e "s/^\([^=]\+\)=\(.*\)$/export \1='\2'/" \
-  "${BUILDDIR}/app_shell_installer/theme/BRANDING")
-
-verify_channel
-
-# Some Debian packaging tools want these set.
-export DEBFULLNAME="${MAINTNAME}"
-export DEBEMAIL="${MAINTMAIL}"
-
-# We'd like to eliminate more of these deps by relying on the 'lsb' package, but
-# that brings in tons of unnecessary stuff, like an mta and rpm. Until that full
-# 'lsb' package is installed by default on DEB distros, we'll have to stick with
-# the LSB sub-packages, to avoid pulling in all that stuff that's not installed
-# by default.
-
-# Generate the dependencies,
-# TODO(mmoss): This is a workaround for a problem where dpkg-shlibdeps was
-# resolving deps using some of our build output shlibs (i.e.
-# out/Release/lib.target/libfreetype.so.6), and was then failing with:
-#   dpkg-shlibdeps: error: no dependency information found for ...
-# It's not clear if we ever want to look in LD_LIBRARY_PATH to resolve deps,
-# but it seems that we don't currently, so this is the most expediant fix.
-SAVE_LDLP=${LD_LIBRARY_PATH:-}
-unset LD_LIBRARY_PATH
-if [ ${TARGETARCH} = "x64" ]; then
-  SHLIB_ARGS="-l${SYSROOT}/usr/lib/x86_64-linux-gnu"
-  SHLIB_ARGS="${SHLIB_ARGS} -l${SYSROOT}/lib/x86_64-linux-gnu"
-else
-  SHLIB_ARGS="-l${SYSROOT}/usr/lib/i386-linux-gnu"
-  SHLIB_ARGS="${SHLIB_ARGS} -l${SYSROOT}/lib/i386-linux-gnu"
-fi
-SHLIB_ARGS="${SHLIB_ARGS} -l${SYSROOT}/usr/lib"
-DPKG_SHLIB_DEPS=$(cd ${SYSROOT} && dpkg-shlibdeps ${SHLIB_ARGS:-} -O \
-                  -e"$BUILDDIR/app_shell" | sed 's/^shlibs:Depends=//')
-if [ -n "$SAVE_LDLP" ]; then
-  LD_LIBRARY_PATH=$SAVE_LDLP
-fi
-
-# Format it nicely and save it for comparison.
-echo "$DPKG_SHLIB_DEPS" | sed 's/, /\n/g' | LANG=C sort > actual
-
-# Compare the expected dependency list to the generated list.
-BAD_DIFF=0
-diff -u "$SCRIPTDIR/expected_deps_${TARGETARCH}_${TARGET_DISTRO}" actual || \
-  BAD_DIFF=1
-if [ $BAD_DIFF -ne 0 ] && [ -z "${IGNORE_DEPS_CHANGES:-}" ]; then
-  echo
-  echo "ERROR: Shared library dependencies changed!"
-  echo "If this is intentional, please update:"
-  echo "extensions/shell/installer/linux/debian/expected_deps_*"
-  echo
-  exit $BAD_DIFF
-fi
-
-# Additional dependencies not in the dpkg-shlibdeps output.
-# ca-certificates: Make sure users have SSL certificates.
-# libnss3: Pull a more recent version of NSS than required by runtime linking,
-#          for security and stability updates in NSS.
-# lsb-release: For lsb-release.
-# wget: For uploading crash reports with Breakpad.
-ADDITIONAL_DEPS="ca-certificates, libnss3 (>= 3.26), lsb-release, wget"
-
-# Fix-up libnspr dependency due to renaming in Ubuntu (the old package still
-# exists, but it was moved to "universe" repository, which isn't installed by
-# default).
-DPKG_SHLIB_DEPS=$(sed \
-    's/\(libnspr4-0d ([^)]*)\), /\1 | libnspr4 (>= 4.9.5-0ubuntu0), /g' \
-    <<< $DPKG_SHLIB_DEPS)
-
-# Remove libnss dependency so the one in $ADDITIONAL_DEPS can supercede it.
-DPKG_SHLIB_DEPS=$(sed 's/\(libnss3 ([^)]*)\), //g' <<< $DPKG_SHLIB_DEPS)
-
-COMMON_DEPS="${DPKG_SHLIB_DEPS}, ${ADDITIONAL_DEPS}"
-COMMON_PREDEPS="dpkg (>= 1.14.0)"
-
-
-# Make everything happen in the OUTPUTDIR.
-cd "${OUTPUTDIR}"
-
-case "$TARGETARCH" in
-  ia32 )
-    export ARCHITECTURE="i386"
-    ;;
-  x64 )
-    export ARCHITECTURE="amd64"
-    ;;
-  * )
-    echo
-    echo "ERROR: Don't know how to build DEBs for '$TARGETARCH'."
-    echo
-    exit 1
-    ;;
-esac
-# TODO(michaelpg): Get a working repo URL.
-BASEREPOCONFIG="dl.google.com/linux/app-shell/deb/ stable main"
-# Only use the default REPOCONFIG if it's unset (e.g. verify_channel might have
-# set it to an empty string)
-REPOCONFIG="${REPOCONFIG-deb [arch=${ARCHITECTURE}] http://${BASEREPOCONFIG}}"
-# Allowed configs include optional HTTPS support and explicit multiarch
-# platforms.
-REPOCONFIGREGEX="deb (\\\\[arch=[^]]*\\\\b${ARCHITECTURE}\\\\b[^]]*\\\\]"
-REPOCONFIGREGEX+="[[:space:]]*) https?://${BASEREPOCONFIG}"
-stage_install_debian
-
-do_package
-verify_package
diff --git a/extensions/shell/installer/linux/debian/expected_deps_x64_jessie b/extensions/shell/installer/linux/debian/expected_deps_x64_jessie
deleted file mode 100644
index 5fc6eff..0000000
--- a/extensions/shell/installer/linux/debian/expected_deps_x64_jessie
+++ /dev/null
@@ -1,28 +0,0 @@
-gconf-service
-libasound2 (>= 1.0.16)
-libatk1.0-0 (>= 1.12.4)
-libc6 (>= 2.15)
-libdbus-1-3 (>= 1.1.4)
-libexpat1 (>= 2.0.1)
-libfontconfig1 (>= 2.11)
-libgcc1 (>= 1:4.1.1)
-libgconf-2-4 (>= 3.2.5)
-libglib2.0-0 (>= 2.14.0)
-libnspr4 (>= 2:4.9-2~)
-libnss3 (>= 2:3.13.4-2~)
-libpango-1.0-0 (>= 1.14.0)
-libpangocairo-1.0-0 (>= 1.14.0)
-libstdc++6 (>= 4.8.1)
-libx11-6 (>= 2:1.4.99.1)
-libx11-xcb1
-libxcb1 (>= 1.6)
-libxcomposite1 (>= 1:0.3-1)
-libxcursor1 (>> 1.1.2)
-libxdamage1 (>= 1:1.1)
-libxext6
-libxfixes3
-libxi6 (>= 2:1.2.99.4)
-libxrandr2
-libxrender1
-libxss1
-libxtst6
diff --git a/extensions/shell/installer/linux/debian/postinst b/extensions/shell/installer/linux/debian/postinst
deleted file mode 100755
index 68aa893..0000000
--- a/extensions/shell/installer/linux/debian/postinst
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-set -e
-
-@@include@@../common/apt.include
-
-@@include@@../common/symlinks.include
-
-remove_udev_symlinks
-
-## MAIN ##
-if [ ! -e "$DEFAULTS_FILE" ]; then
-  echo 'repo_add_once="true"' > "$DEFAULTS_FILE"
-  echo 'repo_reenable_on_distupgrade="true"' >> "$DEFAULTS_FILE"
-fi
-
-# Run the cron job immediately to perform repository configuration.
-nohup sh /etc/cron.daily/@@PACKAGE@@ > /dev/null 2>&1 &
diff --git a/extensions/shell/installer/linux/debian/postrm b/extensions/shell/installer/linux/debian/postrm
deleted file mode 100755
index 6d369e7..0000000
--- a/extensions/shell/installer/linux/debian/postrm
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-set -e
-
-action="$1"
-
-# Only do complete clean-up on purge.
-if [ "$action" != "purge" ] ; then
-  exit 0
-fi
-
-@@include@@../common/apt.include
-
-@@include@@../common/symlinks.include
-
-remove_udev_symlinks
-
-# Only remove the defaults file if it is not empty. An empty file was probably
-# put there by the sysadmin to disable automatic repository configuration, as
-# per the instructions on the package download page.
-if [ -s "$DEFAULTS_FILE" ]; then
-  # Make sure the package defaults are removed before the repository config,
-  # otherwise it could result in the repository config being removed, but the
-  # package defaults remain and are set to not recreate the repository config.
-  # In that case, future installs won't recreate it and won't get auto-updated.
-  rm "$DEFAULTS_FILE" || exit 1
-fi
-# Remove any Google repository added by the package.
-clean_sources_lists
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 5149254..baa2852 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -394,10 +394,7 @@
   void Create();
 
   // Set the initial size and format of a render buffer or resize it.
-  bool AllocateStorage(const FeatureInfo* feature_info,
-                       const gfx::Size& size,
-                       GLenum format,
-                       GLsizei samples);
+  bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
 
   // Destroy the render buffer. This must be explicitly called before destroying
   // this object.
@@ -631,13 +628,17 @@
   void EnsureRenderbufferBound();
 
   // Helpers to facilitate calling into compatible extensions.
-  static void RenderbufferStorageMultisampleHelper(
-      const FeatureInfo* feature_info,
-      GLenum target,
-      GLsizei samples,
-      GLenum internal_format,
-      GLsizei width,
-      GLsizei height);
+  void RenderbufferStorageMultisampleWithWorkaround(GLenum target,
+                                                    GLsizei samples,
+                                                    GLenum internal_format,
+                                                    GLsizei width,
+                                                    GLsizei height);
+  void RenderbufferStorageMultisampleHelper(GLenum target,
+                                            GLsizei samples,
+                                            GLenum internal_format,
+                                            GLsizei width,
+                                            GLsizei height);
+  bool RegenerateRenderbufferIfNeeded(Renderbuffer* renderbuffer);
 
   void BlitFramebufferHelper(GLint srcX0,
                              GLint srcY0,
@@ -2904,8 +2905,7 @@
   glGenRenderbuffersEXT(1, &id_);
 }
 
-bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
-                                       const gfx::Size& size,
+bool BackRenderbuffer::AllocateStorage(const gfx::Size& size,
                                        GLenum format,
                                        GLsizei samples) {
   ScopedGLErrorSuppressor suppressor("BackRenderbuffer::AllocateStorage",
@@ -2922,18 +2922,25 @@
     return false;
   }
 
+  // TODO(kainino): "samples <= 1" is technically incorrect (it should be
+  // "samples == 0"), but it causes framebuffer incompleteness in some
+  // situations. Once this is fixed, this entire arm is no longer necessary -
+  // RenderbufferStorageMultisampleHelper implements it. http://crbug.com/731286
   if (samples <= 1) {
     glRenderbufferStorageEXT(GL_RENDERBUFFER,
                              format,
                              size.width(),
                              size.height());
   } else {
-    GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
-                                                           GL_RENDERBUFFER,
-                                                           samples,
-                                                           format,
-                                                           size.width(),
-                                                           size.height());
+    // TODO(kainino): This path will not perform RegenerateRenderbufferIfNeeded
+    // on devices where multisample_renderbuffer_resize_emulation is needed.
+    // Thus any code using this path (pepper?) could encounter issues on those
+    // devices. RenderbufferStorageMultisampleWithWorkaround should be used
+    // instead, but can only be used if BackRenderbuffer tracks its
+    // renderbuffers in the renderbuffer manager instead of manually.
+    // http://crbug.com/731287
+    decoder_->RenderbufferStorageMultisampleHelper(
+        GL_RENDERBUFFER, samples, format, size.width(), size.height());
   }
 
   bool alpha_channel_needs_clear =
@@ -5034,8 +5041,8 @@
   DCHECK(offscreen_target_color_format_);
   if (IsOffscreenBufferMultisampled()) {
     if (!offscreen_target_color_render_buffer_->AllocateStorage(
-            feature_info_.get(), offscreen_size_,
-            offscreen_target_color_format_, offscreen_target_samples_)) {
+            offscreen_size_, offscreen_target_color_format_,
+            offscreen_target_samples_)) {
       LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
                  << "to allocate storage for offscreen target color buffer.";
       return false;
@@ -5050,9 +5057,7 @@
   }
   if (offscreen_target_depth_format_ &&
       !offscreen_target_depth_render_buffer_->AllocateStorage(
-          feature_info_.get(),
-          offscreen_size_,
-          offscreen_target_depth_format_,
+          offscreen_size_, offscreen_target_depth_format_,
           offscreen_target_samples_)) {
     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
                << "to allocate storage for offscreen target depth buffer.";
@@ -5060,9 +5065,7 @@
   }
   if (offscreen_target_stencil_format_ &&
       !offscreen_target_stencil_render_buffer_->AllocateStorage(
-          feature_info_.get(),
-          offscreen_size_,
-          offscreen_target_stencil_format_,
+          offscreen_size_, offscreen_target_stencil_format_,
           offscreen_target_samples_)) {
     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
                << "to allocate storage for offscreen target stencil buffer.";
@@ -5745,6 +5748,7 @@
 }
 
 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
+  DCHECK_EQ(target, (GLenum)GL_RENDERBUFFER);
   Renderbuffer* renderbuffer = NULL;
   GLuint service_id = 0;
   if (client_id != 0) {
@@ -8368,19 +8372,38 @@
   }
 }
 
-void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
-    const FeatureInfo* feature_info,
+void GLES2DecoderImpl::RenderbufferStorageMultisampleWithWorkaround(
     GLenum target,
     GLsizei samples,
     GLenum internal_format,
     GLsizei width,
     GLsizei height) {
+  RegenerateRenderbufferIfNeeded(state_.bound_renderbuffer.get());
+  EnsureRenderbufferBound();
+  RenderbufferStorageMultisampleHelper(target, samples, internal_format, width,
+                                       height);
+}
+
+void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
+    GLenum target,
+    GLsizei samples,
+    GLenum internal_format,
+    GLsizei width,
+    GLsizei height) {
+  if (samples == 0) {
+    glRenderbufferStorageEXT(target, internal_format, width, height);
+    return;
+  }
+
   // TODO(sievers): This could be resolved at the GL binding level, but the
   // binding process is currently a bit too 'brute force'.
-  if (feature_info->feature_flags().use_core_framebuffer_multisample) {
+  if (features().use_img_for_multisampled_render_to_texture) {
+    glRenderbufferStorageMultisampleIMG(target, samples, internal_format, width,
+                                        height);
+  } else if (features().use_core_framebuffer_multisample) {
     glRenderbufferStorageMultisample(
         target, samples, internal_format, width, height);
-  } else if (feature_info->feature_flags().angle_framebuffer_multisample) {
+  } else if (features().angle_framebuffer_multisample) {
     // This is ES2 only.
     glRenderbufferStorageMultisampleANGLE(
         target, samples, internal_format, width, height);
@@ -8390,6 +8413,26 @@
   }
 }
 
+bool GLES2DecoderImpl::RegenerateRenderbufferIfNeeded(
+    Renderbuffer* renderbuffer) {
+  if (!workarounds().multisample_renderbuffer_resize_emulation) {
+    return false;
+  }
+
+  if (!renderbuffer->RegenerateAndBindBackingObjectIfNeeded()) {
+    return false;
+  }
+
+  if (renderbuffer != state_.bound_renderbuffer.get()) {
+    // The renderbuffer bound in the driver has changed to the new
+    // renderbuffer->service_id(). If that isn't state_.bound_renderbuffer,
+    // then state_.bound_renderbuffer is no longer bound in the driver.
+    state_.bound_renderbuffer_valid = false;
+  }
+
+  return true;
+}
+
 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
                                              GLint srcY0,
                                              GLint srcX1,
@@ -8470,14 +8513,13 @@
     return;
   }
 
-  EnsureRenderbufferBound();
   GLenum impl_format =
       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
           internalformat);
   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
       "glRenderbufferStorageMultisampleCHROMIUM");
-  RenderbufferStorageMultisampleHelper(
-      feature_info_.get(), target, samples, impl_format, width, height);
+  RenderbufferStorageMultisampleWithWorkaround(target, samples, impl_format,
+                                               width, height);
   GLenum error =
       LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
   if (error == GL_NO_ERROR) {
@@ -8513,18 +8555,12 @@
     return;
   }
 
-  EnsureRenderbufferBound();
   GLenum impl_format =
       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
           internalformat);
   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
-  if (features().use_img_for_multisampled_render_to_texture) {
-    glRenderbufferStorageMultisampleIMG(
-        target, samples, impl_format, width, height);
-  } else {
-    glRenderbufferStorageMultisampleEXT(
-        target, samples, impl_format, width, height);
-  }
+  RenderbufferStorageMultisampleWithWorkaround(target, samples, impl_format,
+                                               width, height);
   GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
   if (error == GL_NO_ERROR) {
     renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, samples,
@@ -8668,14 +8704,12 @@
     return;
   }
 
-  EnsureRenderbufferBound();
   LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
-  glRenderbufferStorageEXT(
-      target,
+  RenderbufferStorageMultisampleWithWorkaround(
+      target, 0,
       renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
           internalformat),
-      width,
-      height);
+      width, height);
   GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
   if (error == GL_NO_ERROR) {
     renderbuffer_manager()->SetInfoAndInvalidate(renderbuffer, 0,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 79d67d33..4dfe0539f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -1184,10 +1184,12 @@
     GLenum internal_format,
     GLenum gl_format,
     GLsizei width,
-    GLsizei height) {
+    GLsizei height,
+    bool expect_bind) {
   EXPECT_CALL(*gl_, GetError())
       .WillOnce(Return(GL_NO_ERROR))
       .RetiresOnSaturation();
+  EnsureRenderbufferBound(expect_bind);
   EXPECT_CALL(*gl_,
               RenderbufferStorageMultisampleEXT(
                   target, samples, gl_format, width, height))
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
index d32f281..d268fc1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h
@@ -293,7 +293,8 @@
                                                 GLenum internal_format,
                                                 GLenum gl_format,
                                                 GLsizei width,
-                                                GLsizei height);
+                                                GLsizei height,
+                                                bool expect_bind);
   void RestoreRenderbufferBindings();
   void EnsureRenderbufferBound(bool expect_bind);
   void DoBindTexture(GLenum target, GLuint client_id, GLuint service_id);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
index 91f06007..03a1d02 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -2305,13 +2305,9 @@
   DoBindRenderbuffer(
       GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
   InSequence sequence;
-  EnsureRenderbufferBound(false);
-  DoRenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER,
-                                           TestHelper::kMaxSamples,
-                                           GL_RGBA4,
-                                           GL_RGBA,
-                                           TestHelper::kMaxRenderbufferSize,
-                                           1);
+  DoRenderbufferStorageMultisampleCHROMIUM(
+      GL_RENDERBUFFER, TestHelper::kMaxSamples, GL_RGBA4, GL_RGBA,
+      TestHelper::kMaxRenderbufferSize, 1, false);
 }
 
 TEST_P(GLES2DecoderManualInitTest,
@@ -2323,13 +2319,9 @@
       GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
   RestoreRenderbufferBindings();
   InSequence sequence;
-  EnsureRenderbufferBound(true);
-  DoRenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER,
-                                           TestHelper::kMaxSamples,
-                                           GL_RGBA4,
-                                           GL_RGBA,
-                                           TestHelper::kMaxRenderbufferSize,
-                                           1);
+  DoRenderbufferStorageMultisampleCHROMIUM(
+      GL_RENDERBUFFER, TestHelper::kMaxSamples, GL_RGBA4, GL_RGBA,
+      TestHelper::kMaxRenderbufferSize, 1, true);
 }
 
 TEST_P(GLES2DecoderManualInitTest,
@@ -2371,16 +2363,16 @@
     DoBindRenderbuffer(
         GL_RENDERBUFFER, client_renderbuffer_id_, kServiceRenderbufferId);
     InSequence sequence;
+
+    EXPECT_CALL(*gl_, GetError())
+        .WillOnce(Return(GL_NO_ERROR))
+        .RetiresOnSaturation();
     if (rb_rebind) {
       RestoreRenderbufferBindings();
       EnsureRenderbufferBound(true);
     } else {
       EnsureRenderbufferBound(false);
     }
-
-    EXPECT_CALL(*gl_, GetError())
-        .WillOnce(Return(GL_NO_ERROR))
-        .RetiresOnSaturation();
     if (strstr(extension, "GL_IMG_multisampled_render_to_texture")) {
       EXPECT_CALL(
           *gl_,
diff --git a/gpu/command_buffer/service/renderbuffer_manager.cc b/gpu/command_buffer/service/renderbuffer_manager.cc
index d734547..2174fb93 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.cc
+++ b/gpu/command_buffer/service/renderbuffer_manager.cc
@@ -103,6 +103,7 @@
   width_ = width;
   height_ = height;
   cleared_ = false;
+  allocated_ = true;
   for (auto& point : framebuffer_attachment_points_) {
     point.first->UnmarkAsComplete();
   }
@@ -127,6 +128,7 @@
       client_id_(client_id),
       service_id_(service_id),
       cleared_(true),
+      allocated_(false),
       has_been_bound_(false),
       samples_(0),
       internal_format_(GL_RGBA4),
@@ -135,6 +137,33 @@
   manager_->StartTracking(this);
 }
 
+bool Renderbuffer::RegenerateAndBindBackingObjectIfNeeded() {
+  if (!allocated_ || !has_been_bound_ || samples_ == 0) {
+    // Not needed - won't trigger bug (multisample_renderbuffer_resize_broken).
+    return false;
+  }
+
+  GLint original_fbo = 0;
+  glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &original_fbo);
+
+  glDeleteRenderbuffersEXT(1, &service_id_);
+  service_id_ = 0;
+  glGenRenderbuffersEXT(1, &service_id_);
+  glBindRenderbufferEXT(GL_RENDERBUFFER, service_id_);
+
+  // Attach new renderbuffer to all framebuffers
+  for (auto& point : framebuffer_attachment_points_) {
+    glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, point.first->service_id());
+    glFramebufferRenderbufferEXT(GL_DRAW_FRAMEBUFFER, point.second,
+                                 GL_RENDERBUFFER, service_id_);
+  }
+
+  glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, original_fbo);
+
+  allocated_ = false;
+  return true;
+}
+
 void Renderbuffer::AddFramebufferAttachmentPoint(Framebuffer* framebuffer,
                                                  GLenum attachment) {
   framebuffer_attachment_points_.insert(
diff --git a/gpu/command_buffer/service/renderbuffer_manager.h b/gpu/command_buffer/service/renderbuffer_manager.h
index 698a1d9..e87b1303 100644
--- a/gpu/command_buffer/service/renderbuffer_manager.h
+++ b/gpu/command_buffer/service/renderbuffer_manager.h
@@ -74,6 +74,10 @@
     return has_been_bound_ && !IsDeleted();
   }
 
+  // Regenerates the object backing this client_id, creating a new service_id.
+  // Also reattaches any framebuffers using this renderbuffer.
+  bool RegenerateAndBindBackingObjectIfNeeded();
+
   void AddFramebufferAttachmentPoint(Framebuffer* framebuffer,
                                      GLenum attachment);
   void RemoveFramebufferAttachmentPoint(Framebuffer* framebuffer,
@@ -115,6 +119,9 @@
   // Whether this renderbuffer has been cleared
   bool cleared_;
 
+  // Whether this renderbuffer has been allocated.
+  bool allocated_;
+
   // Whether this renderbuffer has ever been bound.
   bool has_been_bound_;
 
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index a22dbd7..0870a87645 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -408,6 +408,7 @@
 
 void GLManager::SetSurface(gl::GLSurface* surface) {
   decoder_->SetSurface(surface);
+  MakeCurrent();
 }
 
 void GLManager::PerformIdleWork() {
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 0fd2ddd..1dfa1679f 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -1,6 +1,6 @@
 {
   "name": "gpu driver bug list",
-  "version": "10.11",
+  "version": "10.12",
   "entries": [
     {
       "id": 1,
@@ -1053,10 +1053,7 @@
     {
       "id": 116,
       "description": "Adreno 420 support for EXT_multisampled_render_to_texture is buggy on Android < 5.1",
-      "comment": [
-        "Disabling EXT_multisampled_render_to_texture triggers the explicit multisample resolve path, which is broken on Adreno 4xx/5xx."
-      ],
-      "cr_bugs": [490379, 696126],
+      "cr_bugs": [490379],
       "os": {
         "type": "android",
         "version": {
@@ -1067,9 +1064,6 @@
       "gl_renderer": "Adreno \\(TM\\) 4.*",
       "disabled_extensions": [
         "GL_EXT_multisampled_render_to_texture"
-      ],
-      "features": [
-        "disable_chromium_framebuffer_multisample"
       ]
     },
     {
@@ -1744,10 +1738,7 @@
     {
       "id": 174,
       "description": "Adreno 4xx support for EXT_multisampled_render_to_texture is buggy on Android 7.0",
-      "comment": [
-        "Disabling EXT_multisampled_render_to_texture triggers the explicit multisample resolve path, which is broken on Adreno 4xx/5xx."
-      ],
-      "cr_bugs": [612474, 696126],
+      "cr_bugs": [612474],
       "os": {
         "type": "android",
         "version": {
@@ -1760,18 +1751,12 @@
       "gl_renderer": "Adreno \\(TM\\) 4.*",
       "disabled_extensions": [
         "GL_EXT_multisampled_render_to_texture"
-      ],
-      "features": [
-        "disable_chromium_framebuffer_multisample"
       ]
     },
     {
       "id": 175,
       "description": "Adreno 5xx support for EXT_multisampled_render_to_texture is buggy on Android < 7.0",
-      "comment": [
-        "Disabling EXT_multisampled_render_to_texture triggers the explicit multisample resolve path, which is broken on Adreno 4xx/5xx."
-      ],
-      "cr_bugs": [612474, 696126],
+      "cr_bugs": [612474],
       "os": {
         "type": "android",
         "version": {
@@ -1782,9 +1767,6 @@
       "gl_renderer": "Adreno \\(TM\\) 5.*",
       "disabled_extensions": [
         "GL_EXT_multisampled_render_to_texture"
-      ],
-      "features": [
-        "disable_chromium_framebuffer_multisample"
       ]
     },
     {
@@ -2172,10 +2154,7 @@
     {
       "id": 205,
       "description": "Adreno 5xx support for EXT_multisampled_render_to_texture is buggy on Android 7.1",
-      "comment": [
-        "Disabling EXT_multisampled_render_to_texture triggers the explicit multisample resolve path, which is broken on Adreno 4xx/5xx."
-      ],
-      "cr_bugs": [663811, 696126],
+      "cr_bugs": [663811],
       "os": {
         "type": "android",
         "version": {
@@ -2186,9 +2165,6 @@
       "gl_renderer": "Adreno \\(TM\\) 5.*",
       "disabled_extensions": [
         "GL_EXT_multisampled_render_to_texture"
-      ],
-      "features": [
-        "disable_chromium_framebuffer_multisample"
       ]
     },
     {
@@ -2508,6 +2484,18 @@
       "features": [
         "disable_d3d11"
       ]
+    },
+    {
+      "id": 231,
+      "description": "Multisampled color renderbuffers can't be resized on Qualcomm 4xx/5xx",
+      "cr_bugs": [696126],
+      "os": {
+        "type": "android"
+      },
+      "gl_renderer": "Adreno \\(TM\\) [45].*",
+      "features": [
+        "multisample_renderbuffer_resize_emulation"
+      ]
     }
   ],
   "comment": [
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h
index bcf07fc..5b0f4eb 100644
--- a/gpu/config/gpu_driver_bug_workaround_type.h
+++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -23,6 +23,8 @@
          avoid_egl_image_target_texture_reuse)               \
   GPU_OP(AVOID_ONE_COMPONENT_EGL_IMAGES,                     \
          avoid_one_component_egl_images)                     \
+  GPU_OP(AVOID_STENCIL_BUFFERS,                              \
+         avoid_stencil_buffers)                              \
   GPU_OP(BROKEN_EGL_IMAGE_REF_COUNTING,                      \
          broken_egl_image_ref_counting)                      \
   GPU_OP(CLEAR_ALPHA_IN_READPIXELS,                          \
@@ -69,6 +71,8 @@
          disable_larger_than_screen_overlays)                \
   GPU_OP(DISABLE_MULTIMONITOR_MULTISAMPLING,                 \
          disable_multimonitor_multisampling)                 \
+  GPU_OP(DISABLE_NON_EMPTY_POST_SUB_BUFFERS_FOR_ONSCREEN_SURFACES, \
+         disable_non_empty_post_sub_buffers_for_onscreen_surfaces) \
   GPU_OP(DISABLE_NV12_DXGI_VIDEO,                            \
          disable_nv12_dxgi_video)                            \
   GPU_OP(DISABLE_OVERLAY_CA_LAYERS,                          \
@@ -81,6 +85,8 @@
          disable_program_caching_for_transform_feedback)     \
   GPU_OP(DISABLE_PROGRAM_DISK_CACHE,                         \
          disable_program_disk_cache)                         \
+  GPU_OP(DISABLE_SOFTWARE_TO_ACCELERATED_CANVAS_UPGRADE,     \
+         disable_software_to_accelerated_canvas_upgrade)     \
   GPU_OP(DISABLE_TEXTURE_CUBE_MAP_SEAMLESS,                  \
          disable_texture_cube_map_seamless)                  \
   GPU_OP(DISABLE_TEXTURE_STORAGE,                            \
@@ -91,6 +97,8 @@
          disable_multisampling_color_mask_usage)             \
   GPU_OP(DISABLE_WEBGL_RGB_MULTISAMPLING_USAGE,              \
          disable_webgl_rgb_multisampling_usage)              \
+  GPU_OP(DISALLOW_LARGE_INSTANCED_DRAW,                      \
+         disallow_large_instanced_draw)                      \
   GPU_OP(DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT,           \
          dont_remove_invariant_for_fragment_input)           \
   GPU_OP(ETC1_POWER_OF_TWO_ONLY,                             \
@@ -143,6 +151,8 @@
          max_vertex_uniform_vectors_256)                     \
   GPU_OP(MSAA_IS_SLOW,                                       \
          msaa_is_slow)                                       \
+  GPU_OP(MULTISAMPLE_RENDERBUFFER_RESIZE_EMULATION,          \
+         multisample_renderbuffer_resize_emulation)          \
   GPU_OP(NEEDS_OFFSCREEN_BUFFER_WORKAROUND,                  \
          needs_offscreen_buffer_workaround)                  \
   GPU_OP(PACK_PARAMETERS_WORKAROUND_WITH_PACK_BUFFER,        \
@@ -197,6 +207,8 @@
          unpack_overlapping_rows_separately_unpack_buffer)   \
   GPU_OP(USE_CLIENT_SIDE_ARRAYS_FOR_STREAM_BUFFERS,          \
          use_client_side_arrays_for_stream_buffers)          \
+  GPU_OP(USE_GPU_DRIVER_WORKAROUND_FOR_TESTING,              \
+         use_gpu_driver_workaround_for_testing)              \
   GPU_OP(USE_INTERMEDIARY_FOR_COPY_TEXTURE_IMAGE,            \
          use_intermediary_for_copy_texture_image)            \
   GPU_OP(USE_NON_ZERO_SIZE_FOR_CLIENT_SIDE_STREAM_BUFFERS,   \
@@ -211,16 +223,6 @@
          validate_multisample_buffer_allocation)             \
   GPU_OP(WAKE_UP_GPU_BEFORE_DRAWING,                         \
          wake_up_gpu_before_drawing)                         \
-  GPU_OP(USE_GPU_DRIVER_WORKAROUND_FOR_TESTING,              \
-         use_gpu_driver_workaround_for_testing)              \
-  GPU_OP(DISALLOW_LARGE_INSTANCED_DRAW,                      \
-         disallow_large_instanced_draw)                      \
-  GPU_OP(DISABLE_SOFTWARE_TO_ACCELERATED_CANVAS_UPGRADE,     \
-         disable_software_to_accelerated_canvas_upgrade)     \
-  GPU_OP(DISABLE_NON_EMPTY_POST_SUB_BUFFERS_FOR_ONSCREEN_SURFACES, \
-         disable_non_empty_post_sub_buffers_for_onscreen_surfaces) \
-  GPU_OP(AVOID_STENCIL_BUFFERS,                              \
-         avoid_stencil_buffers)                              \
 // clang-format on
 
 namespace gpu {
diff --git a/gpu/gles2_conform_support/BUILD.gn b/gpu/gles2_conform_support/BUILD.gn
index 136703c..ca9e1a3d 100644
--- a/gpu/gles2_conform_support/BUILD.gn
+++ b/gpu/gles2_conform_support/BUILD.gn
@@ -413,11 +413,6 @@
       # Must be done this way for warning flags to be ordered correctly.
       ":gles2_conform_test_warnings",
     ]
-    if (is_linux) {
-      if (!is_chromeos) {
-        deps += [ "//build/config/linux/gtk2" ]
-      }
-    }
     if (is_win) {
       deps += [
         "//third_party/angle:libEGL",
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg
index 1421b2b5..4f47719d 100644
--- a/infra/config/cq.cfg
+++ b/infra/config/cq.cfg
@@ -33,23 +33,6 @@
 # https://sites.google.com/a/chromium.org/dev/developers/testing/chromium-build-infrastructure/tour-of-the-chromium-buildbot?pli=1#TOC-Adding-new-build-configurations-and-tests-to-the-main-Chromium-waterfall-Commit-Queue
   try_job {
     buckets {
-      name: "luci.chromium.try"
-      # Builders in this bucket are defined in
-      # https://chromium.googlesource.com/chromium/src/+/infra/config/cr-buildbucket.cfg
-      builders {
-        name: "LUCI linux_chromium_rel_ng"
-        experiment_percentage: 10
-      }
-      builders {
-        name: "LUCI mac_chromium_rel_ng"
-        experiment_percentage: 5
-      }
-      builders {
-        name: "LUCI win_chromium_rel_ng"
-        experiment_percentage: 5
-      }
-    }
-    buckets {
       name: "master.tryserver.chromium.android"
       builders { name: "android_arm64_dbg_recipe" }
       builders { name: "android_clang_dbg_recipe" }
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS
index dec0debc..ab359780 100644
--- a/ios/chrome/browser/DEPS
+++ b/ios/chrome/browser/DEPS
@@ -79,6 +79,7 @@
   "+components/toolbar",
   "+components/translate/core",
   "+components/translate/ios",
+  "+components/ui_metrics",
   "+components/ukm",
   "+components/undo",
   "+components/update_client",
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h
index 2eaa9ade5..f3a046b0 100644
--- a/ios/chrome/browser/experimental_flags.h
+++ b/ios/chrome/browser/experimental_flags.h
@@ -103,6 +103,9 @@
 // Whether Google Native App Launcher is enabled.
 bool IsNativeAppLauncherEnabled();
 
+// Whether a new version of FeedbackKit is the preferred feedback UI provider.
+bool IsNewFeedbackKitEnabled();
+
 }  // namespace experimental_flags
 
 #endif  // IOS_CHROME_BROWSER_EXPERIMENTAL_FLAGS_H_
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm
index b6a6097..6dd6b82 100644
--- a/ios/chrome/browser/experimental_flags.mm
+++ b/ios/chrome/browser/experimental_flags.mm
@@ -272,4 +272,9 @@
       boolForKey:@"NativeAppLauncherEnabled"];
 }
 
+bool IsNewFeedbackKitEnabled() {
+  return [[NSUserDefaults standardUserDefaults]
+      boolForKey:@"NewFeedbackKitEnabled"];
+}
+
 }  // namespace experimental_flags
diff --git a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
index 7f4c7dee..1d2328ea 100644
--- a/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
+++ b/ios/chrome/browser/resources/Settings.bundle/Experimental.plist
@@ -424,6 +424,16 @@
 		</dict>
 		<dict>
 			<key>Type</key>
+			<string>PSToggleSwitchSpecifier</string>
+			<key>Title</key>
+			<string>Enable New FeedbackKit</string>
+			<key>Key</key>
+			<string>NewFeedbackKitEnabled</string>
+			<key>DefaultValue</key>
+			<false/>
+		</dict>
+		<dict>
+			<key>Type</key>
 			<string>PSGroupSpecifier</string>
 			<key>Title</key>
 			<string>Memory</string>
diff --git a/ios/chrome/browser/ui/payments/address_edit_mediator.mm b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
index 9b7b3fc..568608fb8 100644
--- a/ios/chrome/browser/ui/payments/address_edit_mediator.mm
+++ b/ios/chrome/browser/ui/payments/address_edit_mediator.mm
@@ -16,6 +16,7 @@
 #include "components/autofill/core/browser/autofill_address_util.h"
 #include "components/autofill/core/browser/autofill_country.h"
 #include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_type.h"
 #include "components/autofill/core/browser/country_combobox_model.h"
 #include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
@@ -127,10 +128,21 @@
 - (void)regionDataLoaderDidSucceedWithRegions:
     (NSMutableArray<NSString*>*)regions {
   self.regions = regions;
-  // Enable the previously disabled field and reset its value to the first
-  // region or nil, if there are no regions.
+  // Enable the previously disabled field.
   self.regionField.enabled = YES;
-  self.regionField.value = regions.count ? regions[0] : nil;
+
+  // If an address is being edited and it has a valid region, the field value is
+  // set to that region. Otherwise, set the field value to nil. If creating an
+  // address, set the first available region as the field value, if possible.
+  if (self.address) {
+    NSString* region =
+        [self fieldValueFromProfile:self.address
+                          fieldType:autofill::ADDRESS_HOME_STATE];
+    self.regionField.value =
+        [self.regions containsObject:region] ? region : nil;
+  } else {
+    self.regionField.value = regions.count ? regions[0] : nil;
+  }
 
   // Notify the view controller asynchronously to allow for the view to update.
   __weak AddressEditMediator* weakSelf = self;
@@ -162,8 +174,17 @@
     }
   }
   _countries = countries;
+
+  // If an address is being edited and it has a valid country code, the selected
+  // country code is set to that value. Otherwise, it is set to the default
+  // country code.
+  NSString* countryCode =
+      [self fieldValueFromProfile:_address
+                        fieldType:autofill::ADDRESS_HOME_COUNTRY];
   _selectedCountryCode =
-      base::SysUTF8ToNSString(countryModel.GetDefaultCountryCode());
+      countryCode && [_countries objectForKey:countryCode]
+          ? countryCode
+          : base::SysUTF8ToNSString(countryModel.GetDefaultCountryCode());
 }
 
 // Queries the region names based on the selected country code.
@@ -214,12 +235,16 @@
       NSNumber* fieldKey = [NSNumber numberWithInt:autofillUIType];
       EditorField* field = self.fieldsMap[fieldKey];
       if (!field) {
+        NSString* value =
+            [self fieldValueFromProfile:self.address
+                              fieldType:autofill::GetFieldTypeFromString(
+                                            autofillType)];
         BOOL required = autofillUIType != AutofillUITypeProfileCompanyName;
         field =
             [[EditorField alloc] initWithAutofillUIType:autofillUIType
                                               fieldType:EditorFieldTypeTextField
                                                   label:nil
-                                                  value:nil
+                                                  value:value
                                                required:required];
         [self.fieldsMap setObject:field forKey:fieldKey];
       }
@@ -269,11 +294,14 @@
       [NSNumber numberWithInt:AutofillUITypeProfileHomePhoneWholeNumber];
   EditorField* field = self.fieldsMap[phoneNumberFieldKey];
   if (!field) {
+    NSString* value =
+        [self fieldValueFromProfile:self.address
+                          fieldType:autofill::PHONE_HOME_WHOLE_NUMBER];
     field = [[EditorField alloc]
         initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber
                      fieldType:EditorFieldTypeTextField
                          label:l10n_util::GetNSString(IDS_IOS_AUTOFILL_PHONE)
-                         value:nil
+                         value:value
                       required:YES];
     [self.fieldsMap setObject:field forKey:phoneNumberFieldKey];
   }
@@ -282,4 +310,14 @@
   return self.fields;
 }
 
+// Takes in an autofill profile and an autofill field type and returns the
+// corresponding field value. Returns nil if |profile| is nullptr.
+- (NSString*)fieldValueFromProfile:(autofill::AutofillProfile*)profile
+                         fieldType:(autofill::ServerFieldType)fieldType {
+  return profile ? base::SysUTF16ToNSString(profile->GetInfo(
+                       autofill::AutofillType(fieldType),
+                       GetApplicationContext()->GetApplicationLocale()))
+                 : nil;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm b/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm
index 6539749a..6444603 100644
--- a/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm
+++ b/ios/chrome/browser/ui/payments/contact_info_edit_mediator.mm
@@ -85,11 +85,8 @@
   self.fields = [[NSMutableArray alloc] init];
 
   if (_paymentRequest->request_payer_name()) {
-    NSString* name = self.profile
-                         ? base::SysUTF16ToNSString(self.profile->GetInfo(
-                               autofill::AutofillType(autofill::NAME_FULL),
-                               GetApplicationContext()->GetApplicationLocale()))
-                         : nil;
+    NSString* name =
+        [self fieldValueFromProfile:self.profile fieldType:autofill::NAME_FULL];
     EditorField* nameField = [[EditorField alloc]
         initWithAutofillUIType:AutofillUITypeProfileFullName
                      fieldType:EditorFieldTypeTextField
@@ -102,11 +99,8 @@
 
   if (_paymentRequest->request_payer_phone()) {
     NSString* phone =
-        self.profile
-            ? base::SysUTF16ToNSString(self.profile->GetInfo(
-                  autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
-                  GetApplicationContext()->GetApplicationLocale()))
-            : nil;
+        [self fieldValueFromProfile:self.profile
+                          fieldType:autofill::PHONE_HOME_WHOLE_NUMBER];
     EditorField* phoneField = [[EditorField alloc]
         initWithAutofillUIType:AutofillUITypeProfileHomePhoneWholeNumber
                      fieldType:EditorFieldTypeTextField
@@ -118,11 +112,8 @@
   }
 
   if (_paymentRequest->request_payer_email()) {
-    NSString* email =
-        self.profile ? base::SysUTF16ToNSString(self.profile->GetInfo(
-                           autofill::AutofillType(autofill::EMAIL_ADDRESS),
-                           GetApplicationContext()->GetApplicationLocale()))
-                     : nil;
+    NSString* email = [self fieldValueFromProfile:self.profile
+                                        fieldType:autofill::EMAIL_ADDRESS];
     EditorField* emailField = [[EditorField alloc]
         initWithAutofillUIType:AutofillUITypeProfileEmailAddress
                      fieldType:EditorFieldTypeTextField
@@ -139,4 +130,14 @@
   return self.fields;
 }
 
+// Takes in an autofill profile and an autofill field type and returns the
+// corresponding field value. Returns nil if |profile| is nullptr.
+- (NSString*)fieldValueFromProfile:(autofill::AutofillProfile*)profile
+                         fieldType:(autofill::ServerFieldType)fieldType {
+  return profile ? base::SysUTF16ToNSString(profile->GetInfo(
+                       autofill::AutofillType(fieldType),
+                       GetApplicationContext()->GetApplicationLocale()))
+                 : nil;
+}
+
 @end
diff --git a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
index 14227ebb..f9fc7ae 100644
--- a/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_edit_view_controller.mm
@@ -327,11 +327,12 @@
     [self.pickerViews setObject:pickerView forKey:key];
     item.inputView = pickerView;
 
-    // Set UIPickerView's default selected row.
+    // Set UIPickerView's default selected row, if possible.
     [pickerView reloadAllComponents];
-    [pickerView selectRow:[options indexOfObject:field.value]
-              inComponent:0
-                 animated:NO];
+    NSUInteger indexOfRow = [options indexOfObject:field.value];
+    if (indexOfRow != NSNotFound) {
+      [pickerView selectRow:indexOfRow inComponent:0 animated:NO];
+    }
   }
 
   // Reload the item.
diff --git a/ios/chrome/browser/ui/sad_tab/BUILD.gn b/ios/chrome/browser/ui/sad_tab/BUILD.gn
index c5bd5f0..4fd01c50 100644
--- a/ios/chrome/browser/ui/sad_tab/BUILD.gn
+++ b/ios/chrome/browser/ui/sad_tab/BUILD.gn
@@ -12,6 +12,7 @@
     "//base",
     "//components/resources",
     "//components/strings",
+    "//components/ui_metrics",
     "//ios/chrome/browser",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/colors",
diff --git a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
index 793be20..89e24dd7 100644
--- a/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
+++ b/ios/chrome/browser/ui/sad_tab/sad_tab_view.mm
@@ -4,9 +4,11 @@
 
 #import "ios/chrome/browser/ui/sad_tab/sad_tab_view.h"
 
+#include "base/metrics/histogram_macros.h"
 #include "base/strings/sys_string_conversions.h"
 #include "components/grit/components_scaled_resources.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/ui_metrics/sadtab_metrics_types.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
@@ -556,9 +558,15 @@
 - (void)handleActionButtonTapped:(id)sender {
   switch (self.mode) {
     case SadTabViewMode::RELOAD:
+      UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabReloadHistogramKey,
+                                ui_metrics::SadTabEvent::BUTTON_CLICKED,
+                                ui_metrics::SadTabEvent::MAX_SAD_TAB_EVENT);
       self.navigationManager->Reload(web::ReloadType::NORMAL, true);
       break;
     case SadTabViewMode::FEEDBACK: {
+      UMA_HISTOGRAM_ENUMERATION(ui_metrics::kSadTabFeedbackHistogramKey,
+                                ui_metrics::SadTabEvent::BUTTON_CLICKED,
+                                ui_metrics::SadTabEvent::MAX_SAD_TAB_EVENT);
       GenericChromeCommand* command =
           [[GenericChromeCommand alloc] initWithTag:IDC_REPORT_AN_ISSUE];
       [self chromeExecuteCommand:command];
diff --git a/media/audio/audio_system.h b/media/audio/audio_system.h
index b5498ad0..8df7fa70 100644
--- a/media/audio/audio_system.h
+++ b/media/audio/audio_system.h
@@ -43,7 +43,7 @@
   virtual ~AudioSystem();
 
   // Callback may receive invalid parameters, it means the specified device is
-  // not found. This is best-effort: valid parameters do not guarantee existance
+  // not found. This is best-effort: valid parameters do not guarantee existence
   // of the device.
   // TODO(olka,tommi): fix all AudioManager implementations to return invalid
   // parameters if the device is not found.
@@ -54,7 +54,7 @@
   // If media::AudioDeviceDescription::IsDefaultDevice(device_id) is true,
   // callback will receive the parameters of the default output device.
   // Callback may receive invalid parameters, it means the specified device is
-  // not found. This is best-effort: valid parameters do not guarantee existance
+  // not found. This is best-effort: valid parameters do not guarantee existence
   // of the device.
   // TODO(olka,tommi): fix all AudioManager implementations to return invalid
   // parameters if the device is not found.
diff --git a/media/formats/mp4/track_run_iterator.cc b/media/formats/mp4/track_run_iterator.cc
index f109873..d3543f40 100644
--- a/media/formats/mp4/track_run_iterator.cc
+++ b/media/formats/mp4/track_run_iterator.cc
@@ -18,8 +18,8 @@
 namespace mp4 {
 
 struct SampleInfo {
-  int size;
-  int duration;
+  uint32_t size;
+  uint32_t duration;
   int cts_offset;
   bool is_keyframe;
   uint32_t cenc_group_description_index;
diff --git a/media/mojo/BUILD.gn b/media/mojo/BUILD.gn
index 0d7923231b..224db04 100644
--- a/media/mojo/BUILD.gn
+++ b/media/mojo/BUILD.gn
@@ -74,6 +74,7 @@
     "common/media_type_converters_unittest.cc",
     "common/mojo_decoder_buffer_converter_unittest.cc",
     "common/mojo_shared_buffer_video_frame_unittest.cc",
+    "interfaces/video_frame_struct_traits_unittest.cc",
     "services/mojo_audio_output_stream_unittest.cc",
     "services/mojo_cdm_allocator_unittest.cc",
   ]
@@ -92,6 +93,7 @@
     "//media/mojo/common",
     "//media/mojo/common:mojo_shared_buffer_video_frame",
     "//media/mojo/interfaces",
+    "//media/mojo/interfaces:test_interfaces",
     "//media/mojo/services:lib",
     "//services/service_manager/tests:interfaces",
     "//testing/gmock",
diff --git a/media/mojo/clients/mojo_decryptor.cc b/media/mojo/clients/mojo_decryptor.cc
index 2a08ae57..4b57ed9a1 100644
--- a/media/mojo/clients/mojo_decryptor.cc
+++ b/media/mojo/clients/mojo_decryptor.cc
@@ -224,27 +224,20 @@
 
 void MojoDecryptor::OnVideoDecoded(const VideoDecodeCB& video_decode_cb,
                                    Status status,
-                                   mojom::VideoFramePtr video_frame,
+                                   const scoped_refptr<VideoFrame>& video_frame,
                                    mojom::FrameResourceReleaserPtr releaser) {
   DVLOG_IF(1, status != kSuccess) << __func__ << "(" << status << ")";
   DVLOG_IF(3, status == kSuccess) << __func__;
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (video_frame.is_null()) {
-    video_decode_cb.Run(status, nullptr);
-    return;
-  }
-
-  scoped_refptr<VideoFrame> frame(video_frame.To<scoped_refptr<VideoFrame>>());
-
   // If using shared memory, ensure that |releaser| is closed when
   // |frame| is destroyed.
-  if (releaser) {
-    frame->AddDestructionObserver(
+  if (video_frame && releaser) {
+    video_frame->AddDestructionObserver(
         base::Bind(&ReleaseFrameResource, base::Passed(&releaser)));
   }
 
-  video_decode_cb.Run(status, frame);
+  video_decode_cb.Run(status, video_frame);
 }
 
 }  // namespace media
diff --git a/media/mojo/clients/mojo_decryptor.h b/media/mojo/clients/mojo_decryptor.h
index 8b88957..e51ba71 100644
--- a/media/mojo/clients/mojo_decryptor.h
+++ b/media/mojo/clients/mojo_decryptor.h
@@ -63,7 +63,7 @@
                       std::vector<mojom::AudioBufferPtr> audio_buffers);
   void OnVideoDecoded(const VideoDecodeCB& video_decode_cb,
                       Status status,
-                      mojom::VideoFramePtr video_frame,
+                      const scoped_refptr<VideoFrame>& video_frame,
                       mojom::FrameResourceReleaserPtr releaser);
 
   base::ThreadChecker thread_checker_;
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc
index e462dcc..ff22797 100644
--- a/media/mojo/clients/mojo_video_decoder.cc
+++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -9,6 +9,7 @@
 #include "base/callback_helpers.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/unguessable_token.h"
 #include "media/base/bind_to_current_loop.h"
@@ -108,18 +109,17 @@
 }
 
 void MojoVideoDecoder::OnVideoFrameDecoded(
-    mojom::VideoFramePtr frame,
+    const scoped_refptr<VideoFrame>& frame,
     const base::Optional<base::UnguessableToken>& release_token) {
   DVLOG(2) << __func__;
   DCHECK(task_runner_->BelongsToCurrentThread());
 
-  scoped_refptr<VideoFrame> video_frame = frame.To<scoped_refptr<VideoFrame>>();
   if (release_token) {
-    video_frame->SetReleaseMailboxCB(
+    frame->SetReleaseMailboxCB(
         BindToCurrentLoop(base::Bind(&MojoVideoDecoder::OnReleaseMailbox,
                                      weak_this_, release_token.value())));
   }
-  output_cb_.Run(std::move(video_frame));
+  output_cb_.Run(frame);
 }
 
 void MojoVideoDecoder::OnReleaseMailbox(
diff --git a/media/mojo/clients/mojo_video_decoder.h b/media/mojo/clients/mojo_video_decoder.h
index 86e5750..ebd96b33 100644
--- a/media/mojo/clients/mojo_video_decoder.h
+++ b/media/mojo/clients/mojo_video_decoder.h
@@ -49,7 +49,7 @@
 
   // mojom::VideoDecoderClient implementation.
   void OnVideoFrameDecoded(
-      mojom::VideoFramePtr frame,
+      const scoped_refptr<VideoFrame>& frame,
       const base::Optional<base::UnguessableToken>& release_token) final;
 
  private:
diff --git a/media/mojo/common/media_type_converters_unittest.cc b/media/mojo/common/media_type_converters_unittest.cc
index 54aa3717..7ba0fa501 100644
--- a/media/mojo/common/media_type_converters_unittest.cc
+++ b/media/mojo/common/media_type_converters_unittest.cc
@@ -18,8 +18,6 @@
 #include "media/base/media_util.h"
 #include "media/base/sample_format.h"
 #include "media/base/test_helpers.h"
-#include "media/base/video_frame.h"
-#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace media {
@@ -35,24 +33,6 @@
   EXPECT_EQ(memcmp(original_data, result_data, length), 0);
 }
 
-// Compare the actual video frame bytes (|rows| rows of |row|bytes| data),
-// skipping any padding that may be in either frame.
-void CompareRowBytes(uint8_t* original_data,
-                     uint8_t* result_data,
-                     size_t rows,
-                     size_t row_bytes,
-                     size_t original_stride,
-                     size_t result_stride) {
-  DCHECK_GE(original_stride, row_bytes);
-  DCHECK_GE(result_stride, row_bytes);
-
-  for (size_t i = 0; i < rows; ++i) {
-    CompareBytes(original_data, result_data, row_bytes);
-    original_data += original_stride;
-    result_data += result_stride;
-  }
-}
-
 void CompareAudioBuffers(SampleFormat sample_format,
                          const scoped_refptr<AudioBuffer>& original,
                          const scoped_refptr<AudioBuffer>& result) {
@@ -80,96 +60,6 @@
                bytes_per_channel * original->channel_count());
 }
 
-void CompareVideoPlane(size_t plane,
-                       const scoped_refptr<VideoFrame>& original,
-                       const scoped_refptr<VideoFrame>& result) {
-  EXPECT_EQ(original->stride(plane), result->stride(plane));
-  EXPECT_EQ(original->row_bytes(plane), result->row_bytes(plane));
-  EXPECT_EQ(original->rows(plane), result->rows(plane));
-  CompareRowBytes(original->data(plane), result->data(plane),
-                  original->rows(plane), original->row_bytes(plane),
-                  original->stride(plane), result->stride(plane));
-}
-
-void CompareVideoFrames(const scoped_refptr<VideoFrame>& original,
-                        const scoped_refptr<VideoFrame>& result) {
-  if (original->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)) {
-    EXPECT_TRUE(result->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
-    return;
-  }
-
-  EXPECT_EQ(original->format(), result->format());
-  EXPECT_EQ(original->coded_size().height(), result->coded_size().height());
-  EXPECT_EQ(original->coded_size().width(), result->coded_size().width());
-  EXPECT_EQ(original->visible_rect().height(), result->visible_rect().height());
-  EXPECT_EQ(original->visible_rect().width(), result->visible_rect().width());
-  EXPECT_EQ(original->natural_size().height(), result->natural_size().height());
-  EXPECT_EQ(original->natural_size().width(), result->natural_size().width());
-
-  CompareVideoPlane(VideoFrame::kYPlane, original, result);
-  CompareVideoPlane(VideoFrame::kUPlane, original, result);
-  CompareVideoPlane(VideoFrame::kVPlane, original, result);
-}
-
-// Returns a color VideoFrame that stores the data in a
-// mojo::SharedBufferHandle.
-scoped_refptr<VideoFrame> CreateMojoSharedBufferColorFrame() {
-  // Create a color VideoFrame to use as reference (data will need to be copied
-  // to a mojo::SharedBufferHandle).
-  const int kWidth = 16;
-  const int kHeight = 9;
-  const base::TimeDelta kTimestamp = base::TimeDelta::FromSeconds(26);
-  scoped_refptr<VideoFrame> color_frame(VideoFrame::CreateColorFrame(
-      gfx::Size(kWidth, kHeight), 255, 128, 24, kTimestamp));
-
-  // Allocate a mojo::SharedBufferHandle big enough to contain
-  // |color_frame|'s data.
-  const size_t allocation_size = VideoFrame::AllocationSize(
-      color_frame->format(), color_frame->coded_size());
-  mojo::ScopedSharedBufferHandle handle =
-      mojo::SharedBufferHandle::Create(allocation_size);
-  EXPECT_TRUE(handle.is_valid());
-
-  // Create a MojoSharedBufferVideoFrame whose dimensions match |color_frame|.
-  const size_t y_plane_size = color_frame->rows(VideoFrame::kYPlane) *
-                              color_frame->stride(VideoFrame::kYPlane);
-  const size_t u_plane_size = color_frame->rows(VideoFrame::kUPlane) *
-                              color_frame->stride(VideoFrame::kUPlane);
-  const size_t v_plane_size = color_frame->rows(VideoFrame::kVPlane) *
-                              color_frame->stride(VideoFrame::kVPlane);
-  scoped_refptr<VideoFrame> frame(MojoSharedBufferVideoFrame::Create(
-      color_frame->format(), color_frame->coded_size(),
-      color_frame->visible_rect(), color_frame->natural_size(),
-      std::move(handle), allocation_size, 0, y_plane_size,
-      y_plane_size + u_plane_size, color_frame->stride(VideoFrame::kYPlane),
-      color_frame->stride(VideoFrame::kUPlane),
-      color_frame->stride(VideoFrame::kVPlane), color_frame->timestamp()));
-  EXPECT_EQ(color_frame->coded_size(), frame->coded_size());
-  EXPECT_EQ(color_frame->visible_rect(), frame->visible_rect());
-  EXPECT_EQ(color_frame->natural_size(), frame->natural_size());
-  EXPECT_EQ(color_frame->rows(VideoFrame::kYPlane),
-            frame->rows(VideoFrame::kYPlane));
-  EXPECT_EQ(color_frame->rows(VideoFrame::kUPlane),
-            frame->rows(VideoFrame::kUPlane));
-  EXPECT_EQ(color_frame->rows(VideoFrame::kVPlane),
-            frame->rows(VideoFrame::kVPlane));
-  EXPECT_EQ(color_frame->stride(VideoFrame::kYPlane),
-            frame->stride(VideoFrame::kYPlane));
-  EXPECT_EQ(color_frame->stride(VideoFrame::kUPlane),
-            frame->stride(VideoFrame::kUPlane));
-  EXPECT_EQ(color_frame->stride(VideoFrame::kVPlane),
-            frame->stride(VideoFrame::kVPlane));
-
-  // Copy all the data from |color_frame| into |frame|.
-  memcpy(frame->data(VideoFrame::kYPlane),
-         color_frame->data(VideoFrame::kYPlane), y_plane_size);
-  memcpy(frame->data(VideoFrame::kUPlane),
-         color_frame->data(VideoFrame::kUPlane), u_plane_size);
-  memcpy(frame->data(VideoFrame::kVPlane),
-         color_frame->data(VideoFrame::kVPlane), v_plane_size);
-  return frame;
-}
-
 }  // namespace
 
 TEST(MediaTypeConvertersTest, ConvertDecoderBuffer_Normal) {
@@ -444,44 +334,6 @@
   CompareAudioBuffers(kSampleFormatPlanarF32, buffer, result);
 }
 
-TEST(MediaTypeConvertersTest, ConvertVideoFrame_EOS) {
-  // Original.
-  scoped_refptr<VideoFrame> buffer(VideoFrame::CreateEOSFrame());
-
-  // Convert to and back.
-  mojom::VideoFramePtr ptr(mojom::VideoFrame::From(buffer));
-  scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
-
-  // Compare.
-  CompareVideoFrames(buffer, result);
-}
-
-TEST(MediaTypeConvertersTest, ConvertVideoFrame_EmptyFrame) {
-  // Original.
-  scoped_refptr<VideoFrame> frame(MojoSharedBufferVideoFrame::CreateDefaultI420(
-      gfx::Size(100, 100), base::TimeDelta::FromSeconds(100)));
-
-  // Convert to and back.
-  mojom::VideoFramePtr ptr(mojom::VideoFrame::From(frame));
-  scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
-  EXPECT_NE(result.get(), nullptr);
-
-  // Compare.
-  CompareVideoFrames(frame, result);
-}
-
-TEST(MediaTypeConvertersTest, ConvertVideoFrame_ColorFrame) {
-  scoped_refptr<VideoFrame> frame(CreateMojoSharedBufferColorFrame());
-
-  // Convert to and back.
-  mojom::VideoFramePtr ptr(mojom::VideoFrame::From(frame));
-  scoped_refptr<VideoFrame> result(ptr.To<scoped_refptr<VideoFrame>>());
-  EXPECT_NE(result.get(), nullptr);
-
-  // Compare.
-  CompareVideoFrames(frame, result);
-}
-
 TEST(MediaTypeConvertersTest, ConvertEncryptionSchemeAesCbcWithPattern) {
   // Original.
   EncryptionScheme scheme(EncryptionScheme::CIPHER_MODE_AES_CBC,
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame.cc b/media/mojo/common/mojo_shared_buffer_video_frame.cc
index 13b42ad..1772059 100644
--- a/media/mojo/common/mojo_shared_buffer_video_frame.cc
+++ b/media/mojo/common/mojo_shared_buffer_video_frame.cc
@@ -8,6 +8,8 @@
 #include "base/callback.h"
 #include "base/compiler_specific.h"
 #include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/numerics/safe_math.h"
 
 namespace media {
 
@@ -72,6 +74,52 @@
     return nullptr;
   }
 
+  // Validate that the offsets and strides fit in the buffer.
+  //
+  // We can rely on coded_size.GetArea() being relatively small (compared to the
+  // range of an int) due to the IsValidConfig() check above.
+  //
+  // TODO(sandersd): Allow non-sequential formats.
+  if (NumPlanes(format) != 3) {
+    DLOG(ERROR) << __func__ << " " << VideoPixelFormatToString(format)
+                << " is not supported; only YUV formats are allowed";
+    return nullptr;
+  }
+
+  if (y_stride < 0 || u_stride < 0 || v_stride < 0) {
+    DLOG(ERROR) << __func__ << " Invalid stride";
+    return nullptr;
+  }
+
+  // Safe given sizeof(size_t) >= sizeof(int32_t).
+  size_t y_stride_size_t = y_stride;
+  size_t u_stride_size_t = u_stride;
+  size_t v_stride_size_t = v_stride;
+  if (y_stride_size_t < RowBytes(kYPlane, format, coded_size.width()) ||
+      u_stride_size_t < RowBytes(kUPlane, format, coded_size.width()) ||
+      v_stride_size_t < RowBytes(kVPlane, format, coded_size.width())) {
+    DLOG(ERROR) << __func__ << " Invalid stride";
+    return nullptr;
+  }
+
+  base::CheckedNumeric<size_t> y_rows =
+      Rows(kYPlane, format, coded_size.height());
+  base::CheckedNumeric<size_t> u_rows =
+      Rows(kUPlane, format, coded_size.height());
+  base::CheckedNumeric<size_t> v_rows =
+      Rows(kVPlane, format, coded_size.height());
+
+  base::CheckedNumeric<size_t> y_bound = y_rows * y_stride + y_offset;
+  base::CheckedNumeric<size_t> u_bound = u_rows * u_stride + u_offset;
+  base::CheckedNumeric<size_t> v_bound = v_rows * v_stride + v_offset;
+
+  if (!y_bound.IsValid() || !u_bound.IsValid() || !v_bound.IsValid() ||
+      y_bound.ValueOrDie() > data_size || u_bound.ValueOrDie() > data_size ||
+      v_bound.ValueOrDie() > data_size) {
+    DLOG(ERROR) << __func__ << " Invalid offset";
+    return nullptr;
+  }
+
   // Now allocate the frame and initialize it.
   scoped_refptr<MojoSharedBufferVideoFrame> frame(
       new MojoSharedBufferVideoFrame(format, coded_size, visible_rect,
diff --git a/media/mojo/common/mojo_shared_buffer_video_frame.h b/media/mojo/common/mojo_shared_buffer_video_frame.h
index 945f43e..beee425 100644
--- a/media/mojo/common/mojo_shared_buffer_video_frame.h
+++ b/media/mojo/common/mojo_shared_buffer_video_frame.h
@@ -16,19 +16,8 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 
-namespace mojo {
-template <typename T, typename U>
-struct TypeConverter;
-template <typename T>
-class StructPtr;
-};
-
 namespace media {
 
-namespace mojom {
-class VideoFrame;
-}
-
 // A derived class of media::VideoFrame holding a mojo::SharedBufferHandle
 // which is mapped on constructor and remains so for the lifetime of the
 // object. These frames are ref-counted.
@@ -72,16 +61,19 @@
   // |plane| specified.
   size_t PlaneOffset(size_t plane) const;
 
+  // Returns a reference to the mojo shared memory handle. Caller should
+  // duplicate the handle if they want to extend the lifetime of the buffer.
+  const mojo::SharedBufferHandle& Handle() const;
+
+  // Returns the size of the shared memory.
+  size_t MappedSize() const;
+
   // Sets the callback to be called to free the shared buffer. If not null,
   // it is called on destruction, and is passed ownership of |handle|.
   void SetMojoSharedBufferDoneCB(
       const MojoSharedBufferDoneCB& mojo_shared_buffer_done_cb);
 
  private:
-  // mojo::TypeConverter added as a friend so that MojoSharedBufferVideoFrame
-  // can be transferred across a mojo connection.
-  friend struct mojo::TypeConverter<mojo::StructPtr<mojom::VideoFrame>,
-                                    scoped_refptr<VideoFrame>>;
   friend class MojoDecryptorService;
 
   MojoSharedBufferVideoFrame(VideoPixelFormat format,
@@ -102,14 +94,6 @@
             size_t u_offset,
             size_t v_offset);
 
-  // Returns the mojo shared memory handle. This object continues to own the
-  // handle. Caller should call duplicate the handle if they want to keep a
-  // copy of the shared memory.
-  const mojo::SharedBufferHandle& Handle() const;
-
-  // Returns the size of the shared memory.
-  size_t MappedSize() const;
-
   uint8_t* shared_buffer_data() {
     return reinterpret_cast<uint8_t*>(shared_buffer_mapping_.get());
   };
diff --git a/media/mojo/interfaces/BUILD.gn b/media/mojo/interfaces/BUILD.gn
index 7455360..88e8bcb 100644
--- a/media/mojo/interfaces/BUILD.gn
+++ b/media/mojo/interfaces/BUILD.gn
@@ -51,3 +51,13 @@
     "remoting.mojom",
   ]
 }
+
+mojom("test_interfaces") {
+  testonly = true
+  sources = [
+    "traits_test_service.mojom",
+  ]
+  public_deps = [
+    ":interfaces",
+  ]
+}
diff --git a/media/mojo/interfaces/media_types.mojom b/media/mojo/interfaces/media_types.mojom
index 16612b5..e206edb 100644
--- a/media/mojo/interfaces/media_types.mojom
+++ b/media/mojo/interfaces/media_types.mojom
@@ -247,7 +247,8 @@
 
 // This defines video frame data stored in texture mailboxes.
 struct MailboxVideoFrameData {
-  array<gpu.mojom.MailboxHolder> mailbox_holder;
+  // Size must be kept in sync with media::VideoFrame::kMaxPlanes.
+  array<gpu.mojom.MailboxHolder, 4> mailbox_holder;
 };
 
 struct PipelineStatistics {
diff --git a/media/mojo/interfaces/traits_test_service.mojom b/media/mojo/interfaces/traits_test_service.mojom
new file mode 100644
index 0000000..2d58fa2e
--- /dev/null
+++ b/media/mojo/interfaces/traits_test_service.mojom
@@ -0,0 +1,12 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module media.mojom;
+
+import "media/mojo/interfaces/media_types.mojom";
+
+interface TraitsTestService {
+  [Sync]
+  EchoVideoFrame(VideoFrame? f) => (VideoFrame? pass);
+};
diff --git a/media/mojo/interfaces/typemaps.gni b/media/mojo/interfaces/typemaps.gni
index a69837f2..f485f00 100644
--- a/media/mojo/interfaces/typemaps.gni
+++ b/media/mojo/interfaces/typemaps.gni
@@ -11,4 +11,5 @@
   "//media/mojo/interfaces/media_types.typemap",
   "//media/mojo/interfaces/pipeline_statistics.typemap",
   "//media/mojo/interfaces/video_color_space.typemap",
+  "//media/mojo/interfaces/video_frame.typemap",
 ]
diff --git a/media/mojo/interfaces/video_frame.typemap b/media/mojo/interfaces/video_frame.typemap
new file mode 100644
index 0000000..41a2c94
--- /dev/null
+++ b/media/mojo/interfaces/video_frame.typemap
@@ -0,0 +1,37 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//media/mojo/interfaces/media_types.mojom"
+
+# Additional headers required by any code which would depend on the mojom
+# definition of media.mojom.VideoFrame now that the typemap is applied. Any
+# headers required for the native target type definition should be listed here.
+public_headers = [
+  "//base/memory/ref_counted.h",
+  "//media/base/video_frame.h",
+]
+
+# Headers which contain the relevant StructTraits specialization(s) for any
+# type mappings described by this file.
+traits_headers = [ "//media/mojo/interfaces/video_frame_struct_traits.h" ]
+
+sources = [
+  "video_frame_struct_traits.cc",
+]
+
+# Target dependencies exposed by the public_headers and traits_headers.
+public_deps = [
+  "//base",
+  "//media",
+]
+
+deps = [
+  "//gpu/ipc/common:struct_traits",
+  "//media/base/ipc",
+  "//media/mojo/common:mojo_shared_buffer_video_frame",
+  "//mojo/common:struct_traits",
+  "//ui/gfx/geometry/mojo:struct_traits",
+]
+
+type_mappings = [ "media.mojom.VideoFrame=scoped_refptr<media::VideoFrame>[nullable_is_same_type]" ]
diff --git a/media/mojo/interfaces/video_frame_struct_traits.cc b/media/mojo/interfaces/video_frame_struct_traits.cc
new file mode 100644
index 0000000..4d6aebf4
--- /dev/null
+++ b/media/mojo/interfaces/video_frame_struct_traits.cc
@@ -0,0 +1,161 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/mojo/interfaces/video_frame_struct_traits.h"
+
+#include <utility>
+#include <vector>
+
+#include "base/logging.h"
+#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
+
+namespace mojo {
+
+namespace {
+
+media::mojom::VideoFrameDataPtr MakeVideoFrameData(
+    const scoped_refptr<media::VideoFrame>& input) {
+  // EOS frames contain no data.
+  if (input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM))
+    return nullptr;
+
+  if (input->storage_type() == media::VideoFrame::STORAGE_MOJO_SHARED_BUFFER) {
+    media::MojoSharedBufferVideoFrame* mojo_frame =
+        static_cast<media::MojoSharedBufferVideoFrame*>(input.get());
+
+    mojo::ScopedSharedBufferHandle dup = mojo_frame->Handle().Clone();
+    DCHECK(dup.is_valid());
+
+    return media::mojom::VideoFrameData::NewSharedBufferData(
+        media::mojom::SharedBufferVideoFrameData::New(
+            std::move(dup), mojo_frame->MappedSize(),
+            mojo_frame->stride(media::VideoFrame::kYPlane),
+            mojo_frame->stride(media::VideoFrame::kUPlane),
+            mojo_frame->stride(media::VideoFrame::kVPlane),
+            mojo_frame->PlaneOffset(media::VideoFrame::kYPlane),
+            mojo_frame->PlaneOffset(media::VideoFrame::kUPlane),
+            mojo_frame->PlaneOffset(media::VideoFrame::kVPlane)));
+  }
+
+  if (input->HasTextures()) {
+    std::vector<gpu::MailboxHolder> mailbox_holder(
+        media::VideoFrame::kMaxPlanes);
+    size_t num_planes = media::VideoFrame::NumPlanes(input->format());
+    for (size_t i = 0; i < num_planes; i++)
+      mailbox_holder[i] = input->mailbox_holder(i);
+    return media::mojom::VideoFrameData::NewMailboxData(
+        media::mojom::MailboxVideoFrameData::New(std::move(mailbox_holder)));
+  }
+
+  NOTREACHED() << "Unsupported VideoFrame conversion";
+  return nullptr;
+}
+
+}  // namespace
+
+// static
+void* StructTraits<media::mojom::VideoFrameDataView,
+                   scoped_refptr<media::VideoFrame>>::
+    SetUpContext(const scoped_refptr<media::VideoFrame>& input) {
+  return new media::mojom::VideoFrameDataPtr(MakeVideoFrameData(input));
+}
+
+// static
+void StructTraits<media::mojom::VideoFrameDataView,
+                  scoped_refptr<media::VideoFrame>>::
+    TearDownContext(const scoped_refptr<media::VideoFrame>& input,
+                    void* context) {
+  delete static_cast<media::mojom::VideoFrameDataPtr*>(context);
+}
+
+// static
+media::mojom::VideoFrameDataPtr&
+StructTraits<media::mojom::VideoFrameDataView,
+             scoped_refptr<media::VideoFrame>>::
+    data(const scoped_refptr<media::VideoFrame>& input, void* context) {
+  return *static_cast<media::mojom::VideoFrameDataPtr*>(context);
+}
+
+// static
+bool StructTraits<media::mojom::VideoFrameDataView,
+                  scoped_refptr<media::VideoFrame>>::
+    Read(media::mojom::VideoFrameDataView input,
+         scoped_refptr<media::VideoFrame>* output) {
+  // View of the |data| member of the input media::mojom::VideoFrame.
+  media::mojom::VideoFrameDataDataView data;
+  input.GetDataDataView(&data);
+
+  DCHECK_EQ(input.end_of_stream(), data.is_null());
+  if (input.end_of_stream()) {
+    *output = media::VideoFrame::CreateEOSFrame();
+    return !!*output;
+  }
+
+  media::VideoPixelFormat format;
+  if (!input.ReadFormat(&format))
+    return false;
+
+  gfx::Size coded_size;
+  if (!input.ReadCodedSize(&coded_size))
+    return false;
+
+  gfx::Rect visible_rect;
+  if (!input.ReadVisibleRect(&visible_rect))
+    return false;
+
+  // Coded size must contain the visible rect.
+  if (visible_rect.right() > coded_size.width() ||
+      visible_rect.bottom() > coded_size.height()) {
+    return false;
+  }
+
+  gfx::Size natural_size;
+  if (!input.ReadNaturalSize(&natural_size))
+    return false;
+
+  base::TimeDelta timestamp;
+  if (!input.ReadTimestamp(&timestamp))
+    return false;
+
+  if (data.is_shared_buffer_data()) {
+    media::mojom::SharedBufferVideoFrameDataDataView shared_buffer_data;
+    data.GetSharedBufferDataDataView(&shared_buffer_data);
+
+    // TODO(sandersd): Conversion from uint64_t to size_t could cause
+    // corruption. Platform-dependent types should be removed from the
+    // implementation (limiting to 32-bit offsets is fine).
+    *output = media::MojoSharedBufferVideoFrame::Create(
+        format, coded_size, visible_rect, natural_size,
+        shared_buffer_data.TakeFrameData(),
+        shared_buffer_data.frame_data_size(), shared_buffer_data.y_offset(),
+        shared_buffer_data.u_offset(), shared_buffer_data.v_offset(),
+        shared_buffer_data.y_stride(), shared_buffer_data.u_stride(),
+        shared_buffer_data.v_stride(), timestamp);
+    return !!*output;
+  }
+
+  if (data.is_mailbox_data()) {
+    media::mojom::MailboxVideoFrameDataDataView mailbox_data;
+    data.GetMailboxDataDataView(&mailbox_data);
+
+    std::vector<gpu::MailboxHolder> mailbox_holder;
+    if (!mailbox_data.ReadMailboxHolder(&mailbox_holder))
+      return false;
+
+    gpu::MailboxHolder mailbox_holder_array[media::VideoFrame::kMaxPlanes];
+    for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; i++)
+      mailbox_holder_array[i] = mailbox_holder[i];
+
+    *output = media::VideoFrame::WrapNativeTextures(
+        format, mailbox_holder_array, media::VideoFrame::ReleaseMailboxCB(),
+        coded_size, visible_rect, natural_size, timestamp);
+    return !!*output;
+  }
+
+  // TODO(sandersd): Switch on the union tag to avoid this ugliness?
+  NOTREACHED();
+  return false;
+}
+
+}  // namespace mojo
diff --git a/media/mojo/interfaces/video_frame_struct_traits.h b/media/mojo/interfaces/video_frame_struct_traits.h
new file mode 100644
index 0000000..d674b162
--- /dev/null
+++ b/media/mojo/interfaces/video_frame_struct_traits.h
@@ -0,0 +1,74 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_MOJO_INTERFACES_VIDEO_FRAME_STRUCT_TRAITS_H_
+#define MEDIA_MOJO_INTERFACES_VIDEO_FRAME_STRUCT_TRAITS_H_
+
+#include "base/memory/ref_counted.h"
+#include "gpu/ipc/common/mailbox_holder_struct_traits.h"
+#include "media/base/ipc/media_param_traits_macros.h"
+#include "media/base/video_frame.h"
+#include "media/mojo/interfaces/media_types.mojom.h"
+#include "mojo/common/common_custom_types_struct_traits.h"
+#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
+
+namespace mojo {
+
+template <>
+struct StructTraits<media::mojom::VideoFrameDataView,
+                    scoped_refptr<media::VideoFrame>> {
+  static void* SetUpContext(const scoped_refptr<media::VideoFrame>& input);
+
+  static void TearDownContext(const scoped_refptr<media::VideoFrame>&,
+                              void* context);
+
+  static bool IsNull(const scoped_refptr<media::VideoFrame>& input) {
+    return !input;
+  }
+
+  static void SetToNull(scoped_refptr<media::VideoFrame>* input) {
+    *input = nullptr;
+  }
+
+  static media::VideoPixelFormat format(
+      const scoped_refptr<media::VideoFrame>& input) {
+    return input->format();
+  }
+
+  static const gfx::Size& coded_size(
+      const scoped_refptr<media::VideoFrame>& input) {
+    return input->coded_size();
+  }
+
+  static const gfx::Rect& visible_rect(
+      const scoped_refptr<media::VideoFrame>& input) {
+    return input->visible_rect();
+  }
+
+  static const gfx::Size& natural_size(
+      const scoped_refptr<media::VideoFrame>& input) {
+    return input->natural_size();
+  }
+
+  static bool end_of_stream(const scoped_refptr<media::VideoFrame>& input) {
+    return input->metadata()->IsTrue(media::VideoFrameMetadata::END_OF_STREAM);
+  }
+
+  static base::TimeDelta timestamp(
+      const scoped_refptr<media::VideoFrame>& input) {
+    return input->timestamp();
+  }
+
+  static media::mojom::VideoFrameDataPtr& data(
+      const scoped_refptr<media::VideoFrame>& input,
+      void* context);
+
+  static bool Read(media::mojom::VideoFrameDataView input,
+                   scoped_refptr<media::VideoFrame>* output);
+};
+
+}  // namespace mojo
+
+#endif  // MEDIA_MOJO_INTERFACES_VIDEO_FRAME_STRUCT_TRAITS_H_
diff --git a/media/mojo/interfaces/video_frame_struct_traits_unittest.cc b/media/mojo/interfaces/video_frame_struct_traits_unittest.cc
new file mode 100644
index 0000000..f0ff93b
--- /dev/null
+++ b/media/mojo/interfaces/video_frame_struct_traits_unittest.cc
@@ -0,0 +1,112 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/mojo/interfaces/video_frame_struct_traits.h"
+
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
+#include "gpu/command_buffer/common/sync_token.h"
+#include "media/base/video_frame.h"
+#include "media/mojo/common/mojo_shared_buffer_video_frame.h"
+#include "media/mojo/interfaces/traits_test_service.mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/system/buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace media {
+
+namespace {
+
+class VideoFrameStructTraitsTest : public testing::Test,
+                                   public media::mojom::TraitsTestService {
+ public:
+  VideoFrameStructTraitsTest() = default;
+
+ protected:
+  media::mojom::TraitsTestServicePtr GetTraitsTestProxy() {
+    media::mojom::TraitsTestServicePtr proxy;
+    traits_test_bindings_.AddBinding(this, mojo::MakeRequest(&proxy));
+    return proxy;
+  }
+
+  bool RoundTrip(scoped_refptr<VideoFrame>* frame) {
+    scoped_refptr<VideoFrame> input = std::move(*frame);
+    media::mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
+    return proxy->EchoVideoFrame(std::move(input), frame);
+  }
+
+ private:
+  void EchoVideoFrame(const scoped_refptr<VideoFrame>& f,
+                      EchoVideoFrameCallback callback) override {
+    std::move(callback).Run(f);
+  }
+
+  base::MessageLoop loop_;
+  mojo::BindingSet<TraitsTestService> traits_test_bindings_;
+
+  DISALLOW_COPY_AND_ASSIGN(VideoFrameStructTraitsTest);
+};
+
+}  // namespace
+
+TEST_F(VideoFrameStructTraitsTest, Null) {
+  scoped_refptr<VideoFrame> frame;
+
+  ASSERT_TRUE(RoundTrip(&frame));
+  EXPECT_FALSE(frame);
+}
+
+TEST_F(VideoFrameStructTraitsTest, EOS) {
+  scoped_refptr<VideoFrame> frame = VideoFrame::CreateEOSFrame();
+
+  ASSERT_TRUE(RoundTrip(&frame));
+  ASSERT_TRUE(frame);
+  EXPECT_TRUE(frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
+}
+
+TEST_F(VideoFrameStructTraitsTest, MojoSharedBufferVideoFrame) {
+  scoped_refptr<VideoFrame> frame =
+      MojoSharedBufferVideoFrame::CreateDefaultI420(
+          gfx::Size(100, 100), base::TimeDelta::FromSeconds(100));
+
+  ASSERT_TRUE(RoundTrip(&frame));
+  ASSERT_TRUE(frame);
+  EXPECT_FALSE(frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
+  EXPECT_EQ(frame->coded_size(), gfx::Size(100, 100));
+  EXPECT_EQ(frame->timestamp(), base::TimeDelta::FromSeconds(100));
+
+  ASSERT_EQ(frame->storage_type(), VideoFrame::STORAGE_MOJO_SHARED_BUFFER);
+  MojoSharedBufferVideoFrame* mojo_shared_buffer_frame =
+      static_cast<MojoSharedBufferVideoFrame*>(frame.get());
+  EXPECT_TRUE(mojo_shared_buffer_frame->Handle().is_valid());
+}
+
+TEST_F(VideoFrameStructTraitsTest, MailboxVideoFrame) {
+  gpu::Mailbox mailbox = gpu::Mailbox::Generate();
+  gpu::MailboxHolder mailbox_holder[VideoFrame::kMaxPlanes];
+  mailbox_holder[0] = gpu::MailboxHolder(mailbox, gpu::SyncToken(), 0);
+  scoped_refptr<VideoFrame> frame = VideoFrame::WrapNativeTextures(
+      PIXEL_FORMAT_ARGB, mailbox_holder, VideoFrame::ReleaseMailboxCB(),
+      gfx::Size(100, 100), gfx::Rect(10, 10, 80, 80), gfx::Size(200, 100),
+      base::TimeDelta::FromSeconds(100));
+
+  ASSERT_TRUE(RoundTrip(&frame));
+  ASSERT_TRUE(frame);
+  EXPECT_FALSE(frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
+  EXPECT_EQ(frame->format(), PIXEL_FORMAT_ARGB);
+  EXPECT_EQ(frame->coded_size(), gfx::Size(100, 100));
+  EXPECT_EQ(frame->visible_rect(), gfx::Rect(10, 10, 80, 80));
+  EXPECT_EQ(frame->natural_size(), gfx::Size(200, 100));
+  EXPECT_EQ(frame->timestamp(), base::TimeDelta::FromSeconds(100));
+  ASSERT_TRUE(frame->HasTextures());
+  ASSERT_EQ(frame->mailbox_holder(0).mailbox, mailbox);
+}
+
+}  // namespace media
diff --git a/media/mojo/services/mojo_cdm_allocator_unittest.cc b/media/mojo/services/mojo_cdm_allocator_unittest.cc
index 8fad631..96e8f9b 100644
--- a/media/mojo/services/mojo_cdm_allocator_unittest.cc
+++ b/media/mojo/services/mojo_cdm_allocator_unittest.cc
@@ -85,16 +85,16 @@
 }
 
 TEST_F(MojoCdmAllocatorTest, CreateCdmVideoFrame) {
-  const int kHeight = 16;
-  const int kWidth = 9;
+  const int kWidth = 16;
+  const int kHeight = 9;
   const VideoPixelFormat kFormat = PIXEL_FORMAT_I420;
-  const gfx::Size kSize(kHeight, kWidth);
+  const gfx::Size kSize(kWidth, kHeight);
   const size_t kBufferSize = VideoFrame::AllocationSize(kFormat, kSize);
 
   // Create a VideoFrameImpl and initialize it.
   std::unique_ptr<VideoFrameImpl> video_frame = CreateCdmVideoFrame();
   video_frame->SetFormat(cdm::kI420);
-  video_frame->SetSize(cdm::Size(kHeight, kWidth));
+  video_frame->SetSize(cdm::Size(kWidth, kHeight));
   video_frame->SetStride(VideoFrameImpl::kYPlane,
                          static_cast<uint32_t>(VideoFrame::RowBytes(
                              VideoFrame::kYPlane, kFormat, kWidth)));
diff --git a/media/mojo/services/mojo_decryptor_service.cc b/media/mojo/services/mojo_decryptor_service.cc
index 592bcb6..0e140b7 100644
--- a/media/mojo/services/mojo_decryptor_service.cc
+++ b/media/mojo/services/mojo_decryptor_service.cc
@@ -238,15 +238,13 @@
 
   // If |frame| has shared memory that will be passed back, keep the reference
   // to it until the other side is done with the memory.
-  mojom::VideoFramePtr mojo_frame = mojom::VideoFrame::From(frame);
   mojom::FrameResourceReleaserPtr releaser;
   if (frame->storage_type() == VideoFrame::STORAGE_MOJO_SHARED_BUFFER) {
-    mojo::MakeStrongBinding(
-        base::MakeUnique<FrameResourceReleaserImpl>(std::move(frame)),
-        mojo::MakeRequest(&releaser));
+    mojo::MakeStrongBinding(base::MakeUnique<FrameResourceReleaserImpl>(frame),
+                            mojo::MakeRequest(&releaser));
   }
 
-  callback.Run(status, std::move(mojo_frame), std::move(releaser));
+  callback.Run(status, std::move(frame), std::move(releaser));
 }
 
 }  // namespace media
diff --git a/media/mojo/services/mojo_video_decoder_service.cc b/media/mojo/services/mojo_video_decoder_service.cc
index 2ab3161..d591cab 100644
--- a/media/mojo/services/mojo_video_decoder_service.cc
+++ b/media/mojo/services/mojo_video_decoder_service.cc
@@ -134,7 +134,7 @@
     const scoped_refptr<VideoFrame>& frame) {
   DVLOG(2) << __func__;
   DCHECK(client_);
-  client_->OnVideoFrameDecoded(mojom::VideoFrame::From(frame), base::nullopt);
+  client_->OnVideoFrameDecoded(frame, base::nullopt);
 }
 
 void MojoVideoDecoderService::OnReleaseMailbox(
diff --git a/mojo/edk/system/handle_table_unittest.cc b/mojo/edk/system/handle_table_unittest.cc
index 15bace01..1e72342 100644
--- a/mojo/edk/system/handle_table_unittest.cc
+++ b/mojo/edk/system/handle_table_unittest.cc
@@ -64,7 +64,8 @@
     ht.AddDispatcher(dispatcher);
   }
 
-  base::trace_event::MemoryDumpArgs args;
+  base::trace_event::MemoryDumpArgs args = {
+      base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
   base::trace_event::ProcessMemoryDump pmd(nullptr, args);
   ht.OnMemoryDump(args, &pmd);
 
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc
index 95068d9c..7029fcec 100644
--- a/mojo/edk/system/node_controller.cc
+++ b/mojo/edk/system/node_controller.cc
@@ -662,12 +662,21 @@
   bool needs_introduction = false;
   {
     base::AutoLock lock(peers_lock_);
-    auto& queue = pending_peer_messages_[name];
-    needs_introduction = queue.empty();
-    queue.emplace(std::move(event_message));
+    // We may have been introduced on another thread by the time we get here.
+    // Double-check to be safe.
+    auto it = peers_.find(name);
+    if (it == peers_.end()) {
+      auto& queue = pending_peer_messages_[name];
+      needs_introduction = queue.empty();
+      queue.emplace(std::move(event_message));
+    } else {
+      peer = it->second;
+    }
   }
   if (needs_introduction)
     broker->RequestIntroduction(name);
+  else if (peer)
+    peer->SendChannelMessage(std::move(event_message));
 }
 
 void NodeController::DropAllPeers() {
diff --git a/native_client_sdk/src/tools/common.mk b/native_client_sdk/src/tools/common.mk
index be7e2bbc..5d6b461 100644
--- a/native_client_sdk/src/tools/common.mk
+++ b/native_client_sdk/src/tools/common.mk
@@ -274,7 +274,7 @@
 #
 # Output will be places in a directory name based on Toolchain and configuration
 # be default this will be "newlib/Debug".  We use a python wrapped MKDIR to
-# proivde a cross platform solution. The use of '|' checks for existance instead
+# proivde a cross platform solution. The use of '|' checks for existence instead
 # of timestamp, since the directory can update when files change.
 #
 %dir.stamp :
diff --git a/net/BUILD.gn b/net/BUILD.gn
index b60dd606..4006305 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -154,8 +154,6 @@
     "base/sys_addrinfo.h",
     "base/url_util.cc",
     "base/url_util.h",
-    "base/zap.cc",
-    "base/zap.h",
     "cert/asn1_util.cc",
     "cert/asn1_util.h",
     "cert/cert_database.cc",
diff --git a/net/base/auth.cc b/net/base/auth.cc
index a1af8310..9815ed59 100644
--- a/net/base/auth.cc
+++ b/net/base/auth.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "net/base/auth.h"
-#include "net/base/zap.h"
 
 namespace net {
 
@@ -45,8 +44,4 @@
   return username_.empty() && password_.empty();
 }
 
-void AuthCredentials::Zap() {
-  ZapString(&password_);
-}
-
 }  // namespace net
diff --git a/net/base/auth.h b/net/base/auth.h
index 5f97acb..9db8447 100644
--- a/net/base/auth.h
+++ b/net/base/auth.h
@@ -59,10 +59,6 @@
   // Returns true if all credentials are empty.
   bool Empty() const;
 
-  // Overwrites the password memory to prevent it from being read if
-  // it's paged out to disk.
-  void Zap();
-
   const base::string16& username() const { return username_; }
   const base::string16& password() const { return password_; }
 
diff --git a/net/base/zap.cc b/net/base/zap.cc
deleted file mode 100644
index 81054e6..0000000
--- a/net/base/zap.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011 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 "net/base/zap.h"
-
-#include <string.h>
-
-namespace net {
-
-void ZapBuf(void* buf, size_t buf_len) {
-  memset(buf, 0x0, buf_len);
-}
-
-void ZapString(std::string* s) {
-  if (!s->empty())
-    ZapBuf(&(*s)[0], s->length() * sizeof(char));
-}
-
-void ZapString(base::string16* s) {
-  if (!s->empty())
-    ZapBuf(&(*s)[0], s->length() * sizeof(base::char16));
-}
-
-}  // namespace net
diff --git a/net/base/zap.h b/net/base/zap.h
deleted file mode 100644
index f9c90cd..0000000
--- a/net/base/zap.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2011 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 NET_BASE_ZAP_H_
-#define NET_BASE_ZAP_H_
-
-#include <stddef.h>
-
-#include <string>
-
-#include "base/strings/string16.h"
-
-namespace net {
-
-// Zap functions are used to clear sensitive data in RAM to minimize the
-// time that people can access them once they are written to disk.
-
-// Overwrite a buffer  with 0's.
-void ZapBuf(void* buf, size_t buf_len);
-
-// Overwrite a string's internal buffer with 0's.
-void ZapString(std::string* s);
-
-// Overwrite a base::string16's internal buffer with 0's.
-void ZapString(base::string16* s);
-
-}  // namespace net
-
-#endif  // NET_BASE_ZAP_H_
diff --git a/net/http/http_auth_handler_ntlm_portable.cc b/net/http/http_auth_handler_ntlm_portable.cc
index bb65b308..1f590a0e 100644
--- a/net/http/http_auth_handler_ntlm_portable.cc
+++ b/net/http/http_auth_handler_ntlm_portable.cc
@@ -19,7 +19,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_interfaces.h"
-#include "net/base/zap.h"
 #include "net/http/des.h"
 #include "net/http/md4.h"
 
@@ -245,7 +244,6 @@
   WriteUnicodeLE(passbuf, password.data(), len);
   weak_crypto::MD4Sum(passbuf, len * 2, hash);
 
-  ZapBuf(passbuf, len * 2);
   free(passbuf);
 #else
   weak_crypto::MD4Sum(reinterpret_cast<const uint8_t*>(password.data()),
@@ -270,7 +268,7 @@
   uint8_t keybytes[21], k1[8], k2[8], k3[8];
 
   memcpy(keybytes, hash, 16);
-  ZapBuf(keybytes + 16, 5);
+  memset(keybytes + 16, 0, 5);
 
   DESMakeKey(keybytes, k1);
   DESMakeKey(keybytes + 7, k2);
@@ -594,9 +592,7 @@
   return OK;
 }
 
-HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
-  credentials_.Zap();
-}
+HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {}
 
 // static
 HttpAuthHandlerNTLM::GenerateRandomProc
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index a02cf78..4220ce2d 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -21,11 +21,14 @@
 namespace net {
 
 HttpServerPropertiesImpl::HttpServerPropertiesImpl()
-    : HttpServerPropertiesImpl(&broken_alternative_services_clock_) {}
+    : HttpServerPropertiesImpl(nullptr) {}
 
 HttpServerPropertiesImpl::HttpServerPropertiesImpl(
     base::TickClock* broken_alternative_services_clock)
-    : broken_alternative_services_(this, broken_alternative_services_clock),
+    : broken_alternative_services_(this,
+                                   broken_alternative_services_clock
+                                       ? broken_alternative_services_clock
+                                       : &broken_alternative_services_clock_),
       spdy_servers_map_(SpdyServersMap::NO_AUTO_EVICT),
       alternative_service_map_(AlternativeServiceMap::NO_AUTO_EVICT),
       server_network_stats_map_(ServerNetworkStatsMap::NO_AUTO_EVICT),
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json
index 5653729..9a88fd5 100644
--- a/net/http/transport_security_state_static.json
+++ b/net/http/transport_security_state_static.json
@@ -12749,7 +12749,6 @@
     { "name": "01seguridad.com.ar", "include_subdomains": true, "mode": "force-https" },
     { "name": "0i0.nl", "include_subdomains": true, "mode": "force-https" },
     { "name": "0x52.org", "include_subdomains": true, "mode": "force-https" },
-    { "name": "0xAA55.me", "include_subdomains": true, "mode": "force-https" },
     { "name": "0xaa55.me", "include_subdomains": true, "mode": "force-https" },
     { "name": "0xb612.org", "include_subdomains": true, "mode": "force-https" },
     { "name": "100dayloans.com", "include_subdomains": true, "mode": "force-https" },
diff --git a/net/tools/transport_security_state_generator/input_file_parsers.cc b/net/tools/transport_security_state_generator/input_file_parsers.cc
index 4a63308..2a8d3d8 100644
--- a/net/tools/transport_security_state_generator/input_file_parsers.cc
+++ b/net/tools/transport_security_state_generator/input_file_parsers.cc
@@ -303,6 +303,12 @@
       return false;
     }
 
+    if (entry->hostname.empty()) {
+      LOG(ERROR) << "The hostname for entry " << base::SizeTToString(i)
+                 << " is empty";
+      return false;
+    }
+
     parsed->GetBoolean("include_subdomains", &entry->include_subdomains);
     std::string mode;
     parsed->GetString("mode", &mode);
diff --git a/net/tools/transport_security_state_generator/transport_security_state_generator.cc b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
index d5e98cd..40e8f1d 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_generator.cc
+++ b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
@@ -152,6 +152,50 @@
   return true;
 }
 
+bool IsLowercaseAlphanumeric(char c) {
+  return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
+}
+
+// Checks the well-formedness of the hostnames. All hostnames should be in their
+// canonicalized form because they will be matched against canonicalized input.
+bool CheckHostnames(const TransportSecurityStateEntries& entries) {
+  for (const auto& entry : entries) {
+    const std::string& hostname = entry->hostname;
+
+    bool in_component = false;
+    bool most_recent_component_started_alphanumeric = false;
+    for (const char& c : hostname) {
+      if (!in_component) {
+        most_recent_component_started_alphanumeric = IsLowercaseAlphanumeric(c);
+        if (!most_recent_component_started_alphanumeric && (c != '-') &&
+            (c != '_')) {
+          LOG(ERROR) << hostname << " is not in canonicalized form";
+          return false;
+        }
+        in_component = true;
+      } else if (c == '.') {
+        in_component = false;
+      } else if (!IsLowercaseAlphanumeric(c) && (c != '-') && (c != '_')) {
+        LOG(ERROR) << hostname << " is not in canonicalized form";
+        return false;
+      }
+    }
+
+    if (!most_recent_component_started_alphanumeric) {
+      LOG(ERROR) << "The last label of " << hostname
+                 << " must start with a lowercase alphanumeric character";
+      return false;
+    }
+
+    if (!in_component) {
+      LOG(ERROR) << hostname << " must not end with a \".\"";
+      return false;
+    }
+  }
+
+  return true;
+}
+
 }  // namespace
 
 int main(int argc, char* argv[]) {
@@ -216,7 +260,7 @@
 
   if (!CheckDuplicateEntries(entries) || !CheckNoopEntries(entries) ||
       !CheckSubdomainsFlags(entries) || !CheckForDuplicatePins(pinsets) ||
-      !CheckCertificatesInPinsets(pinsets)) {
+      !CheckCertificatesInPinsets(pinsets) || !CheckHostnames(entries)) {
     LOG(ERROR) << "Checks failed. Aborting.";
     return 1;
   }
diff --git a/services/shape_detection/android/java/src/org/chromium/shape_detection/FaceDetectionImpl.java b/services/shape_detection/android/java/src/org/chromium/shape_detection/FaceDetectionImpl.java
index cb94456..9bef08e2 100644
--- a/services/shape_detection/android/java/src/org/chromium/shape_detection/FaceDetectionImpl.java
+++ b/services/shape_detection/android/java/src/org/chromium/shape_detection/FaceDetectionImpl.java
@@ -5,6 +5,7 @@
 package org.chromium.shape_detection;
 
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.PointF;
 import android.media.FaceDetector;
 import android.media.FaceDetector.Face;
@@ -39,6 +40,17 @@
         // in this case, https://crbug.com/684930.
         Bitmap bitmap = BitmapUtils.convertToBitmap(bitmapData);
 
+        // FaceDetector requires an even width, so pad the image if the width is odd.
+        // https://developer.android.com/reference/android/media/FaceDetector.html#FaceDetector(int, int, int)
+        final int width = bitmapData.width + (bitmapData.width % 2);
+        final int height = bitmapData.height;
+        if (width != bitmapData.width) {
+            Bitmap paddedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            Canvas canvas = new Canvas(paddedBitmap);
+            canvas.drawBitmap(bitmap, 0, 0, null);
+            bitmap = paddedBitmap;
+        }
+
         // A Bitmap must be in 565 format for findFaces() to work. See
         // http://androidxref.com/7.0.0_r1/xref/frameworks/base/media/java/android/media/FaceDetector.java#124
         //
@@ -48,8 +60,6 @@
         // original image is premultiplied. We can use getPixels() which does
         // the unmultiplication while copying to a new array. See
         // http://androidxref.com/7.0.0_r1/xref/frameworks/base/graphics/java/android/graphics/Bitmap.java#538
-        final int width = bitmapData.width;
-        final int height = bitmapData.height;
         int[] pixels = new int[width * height];
         bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
         final Bitmap unPremultipliedBitmap =
diff --git a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java
index b8177d4..5fb16663 100644
--- a/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java
+++ b/services/shape_detection/android/javatests/src/org/chromium/shape_detection/FaceDetectionImplTest.java
@@ -6,6 +6,7 @@
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
 import android.support.test.filters.SmallTest;
 import android.test.InstrumentationTestCase;
 
@@ -83,4 +84,23 @@
         assertEquals(24.0, results[0].boundingBox.x, BOUNDING_BOX_POSITION_ERROR);
         assertEquals(20.0, results[0].boundingBox.y, BOUNDING_BOX_POSITION_ERROR);
     }
+
+    @SmallTest
+    @Feature({"ShapeDetection"})
+    public void testDetectHandlesOddWidths() throws Exception {
+        // Pad the image so that the width is odd.
+        Bitmap paddedBitmap = Bitmap.createBitmap(MONA_LISA_BITMAP.width + 1,
+                MONA_LISA_BITMAP.height, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(paddedBitmap);
+        canvas.drawBitmap(BitmapUtils.convertToBitmap(MONA_LISA_BITMAP), 0, 0, null);
+        org.chromium.skia.mojom.Bitmap mojoBitmap = mojoBitmapFromBitmap(paddedBitmap);
+        assertEquals(1, mojoBitmap.width % 2);
+
+        FaceDetectionResult[] results = detect(mojoBitmap);
+        assertEquals(1, results.length);
+        assertEquals(40.0, results[0].boundingBox.width, BOUNDING_BOX_SIZE_ERROR);
+        assertEquals(40.0, results[0].boundingBox.height, BOUNDING_BOX_SIZE_ERROR);
+        assertEquals(24.0, results[0].boundingBox.x, BOUNDING_BOX_POSITION_ERROR);
+        assertEquals(20.0, results[0].boundingBox.y, BOUNDING_BOX_POSITION_ERROR);
+    }
 }
diff --git a/services/ui/service.cc b/services/ui/service.cc
index b18ee57..052731b 100644
--- a/services/ui/service.cc
+++ b/services/ui/service.cc
@@ -215,9 +215,12 @@
   input_device_server_.RegisterAsObserver();
 
   window_server_.reset(new ws::WindowServer(this));
+  std::unique_ptr<ws::GpuHost> gpu_host =
+      base::MakeUnique<ws::DefaultGpuHost>(window_server_.get());
   std::unique_ptr<ws::FrameSinkManagerClientBinding> frame_sink_manager =
-      base::MakeUnique<ws::FrameSinkManagerClientBinding>(
-          window_server_.get(), window_server_->gpu_host());
+      base::MakeUnique<ws::FrameSinkManagerClientBinding>(window_server_.get(),
+                                                          gpu_host.get());
+  window_server_->SetGpuHost(std::move(gpu_host));
   window_server_->SetFrameSinkManager(std::move(frame_sink_manager));
 
   ime_server_.Init(context()->connector(), test_config_);
diff --git a/services/ui/ws/gpu_host.cc b/services/ui/ws/gpu_host.cc
index 9eac02a6..4b78a4a 100644
--- a/services/ui/ws/gpu_host.cc
+++ b/services/ui/ws/gpu_host.cc
@@ -33,7 +33,7 @@
 
 }  // namespace
 
-GpuHost::GpuHost(GpuHostDelegate* delegate)
+DefaultGpuHost::DefaultGpuHost(GpuHostDelegate* delegate)
     : delegate_(delegate),
       next_client_id_(kInternalGpuChannelClientId + 1),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
@@ -54,31 +54,33 @@
       gpu_service_.get(), next_client_id_++);
 }
 
-GpuHost::~GpuHost() {}
+DefaultGpuHost::~DefaultGpuHost() {}
 
-void GpuHost::Add(mojom::GpuRequest request) {
+void DefaultGpuHost::Add(mojom::GpuRequest request) {
   AddInternal(std::move(request));
 }
 
-void GpuHost::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
+void DefaultGpuHost::OnAcceleratedWidgetAvailable(
+    gfx::AcceleratedWidget widget) {
 #if defined(OS_WIN)
   gfx::RenderingWindowManager::GetInstance()->RegisterParent(widget);
 #endif
 }
 
-void GpuHost::OnAcceleratedWidgetDestroyed(gfx::AcceleratedWidget widget) {
+void DefaultGpuHost::OnAcceleratedWidgetDestroyed(
+    gfx::AcceleratedWidget widget) {
 #if defined(OS_WIN)
   gfx::RenderingWindowManager::GetInstance()->UnregisterParent(widget);
 #endif
 }
 
-void GpuHost::CreateFrameSinkManager(
+void DefaultGpuHost::CreateFrameSinkManager(
     cc::mojom::FrameSinkManagerRequest request,
     cc::mojom::FrameSinkManagerClientPtr client) {
   gpu_main_->CreateFrameSinkManager(std::move(request), std::move(client));
 }
 
-GpuClient* GpuHost::AddInternal(mojom::GpuRequest request) {
+GpuClient* DefaultGpuHost::AddInternal(mojom::GpuRequest request) {
   auto client(base::MakeUnique<GpuClient>(next_client_id_++, &gpu_info_,
                                           gpu_memory_buffer_manager_.get(),
                                           gpu_service_.get()));
@@ -87,32 +89,33 @@
   return client_ref;
 }
 
-void GpuHost::OnBadMessageFromGpu() {
+void DefaultGpuHost::OnBadMessageFromGpu() {
   // TODO(sad): Received some unexpected message from the gpu process. We
   // should kill the process and restart it.
   NOTIMPLEMENTED();
 }
 
-void GpuHost::DidInitialize(const gpu::GPUInfo& gpu_info,
-                            const gpu::GpuFeatureInfo& gpu_feature_info) {
+void DefaultGpuHost::DidInitialize(
+    const gpu::GPUInfo& gpu_info,
+    const gpu::GpuFeatureInfo& gpu_feature_info) {
   gpu_info_ = gpu_info;
   delegate_->OnGpuServiceInitialized();
 }
 
-void GpuHost::DidFailInitialize() {}
+void DefaultGpuHost::DidFailInitialize() {}
 
-void GpuHost::DidCreateOffscreenContext(const GURL& url) {}
+void DefaultGpuHost::DidCreateOffscreenContext(const GURL& url) {}
 
-void GpuHost::DidDestroyOffscreenContext(const GURL& url) {}
+void DefaultGpuHost::DidDestroyOffscreenContext(const GURL& url) {}
 
-void GpuHost::DidDestroyChannel(int32_t client_id) {}
+void DefaultGpuHost::DidDestroyChannel(int32_t client_id) {}
 
-void GpuHost::DidLoseContext(bool offscreen,
-                             gpu::error::ContextLostReason reason,
-                             const GURL& active_url) {}
+void DefaultGpuHost::DidLoseContext(bool offscreen,
+                                    gpu::error::ContextLostReason reason,
+                                    const GURL& active_url) {}
 
-void GpuHost::SetChildSurface(gpu::SurfaceHandle parent,
-                              gpu::SurfaceHandle child) {
+void DefaultGpuHost::SetChildSurface(gpu::SurfaceHandle parent,
+                                     gpu::SurfaceHandle child) {
 #if defined(OS_WIN)
   // Verify that |parent| was created by the window server.
   DWORD process_id = 0;
@@ -133,13 +136,13 @@
 #endif
 }
 
-void GpuHost::StoreShaderToDisk(int32_t client_id,
-                                const std::string& key,
-                                const std::string& shader) {}
+void DefaultGpuHost::StoreShaderToDisk(int32_t client_id,
+                                       const std::string& key,
+                                       const std::string& shader) {}
 
-void GpuHost::RecordLogMessage(int32_t severity,
-                               const std::string& header,
-                               const std::string& message) {}
+void DefaultGpuHost::RecordLogMessage(int32_t severity,
+                                      const std::string& header,
+                                      const std::string& message) {}
 
 }  // namespace ws
 }  // namespace ui
diff --git a/services/ui/ws/gpu_host.h b/services/ui/ws/gpu_host.h
index bb0e0a6..5bb7faf 100644
--- a/services/ui/ws/gpu_host.h
+++ b/services/ui/ws/gpu_host.h
@@ -32,21 +32,27 @@
 
 class GpuHostDelegate;
 
-// Sets up connection from clients to the real service implementation in the GPU
-// process.
-class GpuHost : public mojom::GpuHost {
+// GpuHost sets up connection from clients to the real service implementation in
+// the GPU process.
+class GpuHost {
  public:
-  explicit GpuHost(GpuHostDelegate* delegate);
-  ~GpuHost() override;
+  GpuHost() = default;
+  virtual ~GpuHost() = default;
 
-  void Add(mojom::GpuRequest request);
-
-  void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget);
-  void OnAcceleratedWidgetDestroyed(gfx::AcceleratedWidget widget);
+  virtual void Add(mojom::GpuRequest request) = 0;
+  virtual void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) = 0;
+  virtual void OnAcceleratedWidgetDestroyed(gfx::AcceleratedWidget widget) = 0;
 
   // Requests a cc::mojom::FrameSinkManager interface from mus-gpu.
-  void CreateFrameSinkManager(cc::mojom::FrameSinkManagerRequest request,
-                              cc::mojom::FrameSinkManagerClientPtr client);
+  virtual void CreateFrameSinkManager(
+      cc::mojom::FrameSinkManagerRequest request,
+      cc::mojom::FrameSinkManagerClientPtr client) = 0;
+};
+
+class DefaultGpuHost : public GpuHost, public mojom::GpuHost {
+ public:
+  explicit DefaultGpuHost(GpuHostDelegate* delegate);
+  ~DefaultGpuHost() override;
 
  private:
   friend class test::GpuHostTest;
@@ -54,6 +60,14 @@
   GpuClient* AddInternal(mojom::GpuRequest request);
   void OnBadMessageFromGpu();
 
+  // GpuHost:
+  void Add(mojom::GpuRequest request) override;
+  void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) override;
+  void OnAcceleratedWidgetDestroyed(gfx::AcceleratedWidget widget) override;
+  void CreateFrameSinkManager(
+      cc::mojom::FrameSinkManagerRequest request,
+      cc::mojom::FrameSinkManagerClientPtr client) override;
+
   // mojom::GpuHost:
   void DidInitialize(const gpu::GPUInfo& gpu_info,
                      const gpu::GpuFeatureInfo& gpu_feature_info) override;
@@ -89,7 +103,7 @@
 
   mojo::StrongBindingSet<mojom::Gpu> gpu_bindings_;
 
-  DISALLOW_COPY_AND_ASSIGN(GpuHost);
+  DISALLOW_COPY_AND_ASSIGN(DefaultGpuHost);
 };
 
 }  // namespace ws
diff --git a/services/ui/ws/gpu_host_unittest.cc b/services/ui/ws/gpu_host_unittest.cc
index 7861a3c..a454d52 100644
--- a/services/ui/ws/gpu_host_unittest.cc
+++ b/services/ui/ws/gpu_host_unittest.cc
@@ -87,7 +87,7 @@
   TestGpuHostDelegate gpu_host_delegate_;
   std::unique_ptr<TestGpuService> gpu_service_;
   ui::mojom::GpuServicePtr gpu_service_ptr_;
-  std::unique_ptr<GpuHost> gpu_host_;
+  std::unique_ptr<DefaultGpuHost> gpu_host_;
 
   DISALLOW_COPY_AND_ASSIGN(GpuHostTest);
 };
@@ -103,7 +103,7 @@
 
 void GpuHostTest::SetUp() {
   testing::Test::SetUp();
-  gpu_host_ = base::MakeUnique<GpuHost>(&gpu_host_delegate_);
+  gpu_host_ = base::MakeUnique<DefaultGpuHost>(&gpu_host_delegate_);
   gpu_service_->Bind(mojo::MakeRequest(&gpu_service_ptr_));
   gpu_host_->gpu_service_ = std::move(gpu_service_ptr_);
 }
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc
index 8184c91..50400536 100644
--- a/services/ui/ws/test_utils.cc
+++ b/services/ui/ws/test_utils.cc
@@ -16,6 +16,7 @@
 #include "services/ui/ws/display_creation_config.h"
 #include "services/ui/ws/display_manager.h"
 #include "services/ui/ws/frame_sink_manager_client_binding.h"
+#include "services/ui/ws/gpu_host.h"
 #include "services/ui/ws/window_manager_access_policy.h"
 #include "services/ui/ws/window_manager_window_tree_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -553,6 +554,11 @@
     message_loop_ = base::MakeUnique<base::MessageLoop>();
   PlatformDisplay::set_factory_for_testing(&platform_display_factory_);
   window_server_ = base::MakeUnique<WindowServer>(&window_server_delegate_);
+  // TODO(staraz): Replace DefaultGpuHost and FrameSinkManagerClientBinding with
+  // test implementations.
+  std::unique_ptr<GpuHost> gpu_host =
+      base::MakeUnique<DefaultGpuHost>(window_server_.get());
+  window_server_->SetGpuHost(std::move(gpu_host));
   std::unique_ptr<FrameSinkManagerClientBinding> frame_sink_manager =
       base::MakeUnique<FrameSinkManagerClientBinding>(
           window_server_.get(), window_server_->gpu_host());
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc
index 322cb0c..907540b 100644
--- a/services/ui/ws/window_server.cc
+++ b/services/ui/ws/window_server.cc
@@ -67,7 +67,6 @@
       current_operation_(nullptr),
       in_destructor_(false),
       next_wm_change_id_(0),
-      gpu_host_(new GpuHost(this)),
       window_manager_window_tree_factory_set_(this, &user_id_tracker_),
       display_creation_config_(DisplayCreationConfig::UNKNOWN) {
   user_id_tracker_.AddObserver(this);
@@ -103,6 +102,10 @@
   frame_sink_manager_ = std::move(frame_sink_manager);
 }
 
+void WindowServer::SetGpuHost(std::unique_ptr<GpuHost> gpu_host) {
+  gpu_host_ = std::move(gpu_host);
+}
+
 ServerWindow* WindowServer::CreateServerWindow(
     const WindowId& id,
     const std::map<std::string, std::vector<uint8_t>>& properties) {
diff --git a/services/ui/ws/window_server.h b/services/ui/ws/window_server.h
index 0f3271c..df851a4 100644
--- a/services/ui/ws/window_server.h
+++ b/services/ui/ws/window_server.h
@@ -79,6 +79,8 @@
   void SetFrameSinkManager(
       std::unique_ptr<cc::mojom::FrameSinkManager> frame_sink_manager);
 
+  void SetGpuHost(std::unique_ptr<GpuHost> gpu_host);
+
   // Creates a new ServerWindow. The return value is owned by the caller, but
   // must be destroyed before WindowServer.
   ServerWindow* CreateServerWindow(
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
index d038aa80..93869da 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -79,6 +79,7 @@
 Bug(none) virtual/documentwriteevaluator/ [ Skip ]
 Bug(none) virtual/enable_asmjs/ [ Skip ]
 Bug(none) virtual/enable_wasm/ [ Skip ]
+Bug(none) virtual/exotic-color-space/ [ Skip ]
 Bug(none) virtual/feature-policy/ [ Skip ]
 Bug(none) virtual/gpu/ [ Skip ]
 Bug(none) virtual/gpu-rasterization/ [ Skip ]
@@ -244,7 +245,6 @@
 Bug(none) compositing/iframes/composited-parent-iframe.html [ Failure ]
 Bug(none) compositing/iframes/connect-compositing-iframe2.html [ Failure ]
 Bug(none) compositing/iframes/connect-compositing-iframe3.html [ Failure ]
-Bug(none) compositing/iframes/fixed-position-iframe.html [ Failure ]
 Bug(none) compositing/iframes/iframe-resize.html [ Failure ]
 Bug(none) compositing/iframes/iframe-size-from-zero.html [ Failure ]
 Bug(none) compositing/iframes/invisible-nested-iframe-hide.html [ Crash Failure ]
@@ -320,7 +320,6 @@
 Bug(none) compositing/overflow/descendant-with-clip-path.html [ Failure ]
 Bug(none) compositing/overflow/mask-with-filter.html [ Failure Crash ]
 Bug(none) compositing/overflow/mask-with-small-content-rect.html [ Failure ]
-crbug.com/718971 compositing/overflow/mixed-composited-nested-sticky-overflow-scroller.html [ Failure ]
 Bug(none) compositing/overflow/nested-border-radius-clipping.html [ Failure ]
 Bug(none) compositing/overflow/nested-render-surfaces-with-intervening-clip.html [ Failure Crash ]
 Bug(none) compositing/overflow/nested-render-surfaces-with-rotation.html [ Failure ]
@@ -483,7 +482,6 @@
 Bug(none) fast/block/positioning/relative-overflow-block.html [ Failure ]
 Bug(none) fast/block/positioning/relative-overflow-replaced-float.html [ Failure ]
 Bug(none) fast/block/positioning/relative-overflow-replaced.html [ Failure ]
-Bug(none) fast/block/positioning/rtl-fixed-positioning.html [ Failure ]
 Bug(none) fast/block/positioning/vertical-lr/002.html [ Failure ]
 Bug(none) fast/block/positioning/vertical-rl/002.html [ Failure ]
 Bug(none) fast/body-propagation/overflow/001-xhtml.xhtml [ Failure ]
@@ -1433,7 +1431,6 @@
 Bug(none) paint/invalidation/svg/js-late-gradient-and-object-creation.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-late-gradient-creation.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-late-marker-and-object-creation.svg [ Failure ]
-Bug(none) paint/invalidation/svg/js-late-marker-creation.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-late-pattern-and-object-creation.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-late-pattern-creation.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-repaint-rect-on-path-with-stroke.svg [ Failure ]
@@ -1445,8 +1442,6 @@
 Bug(none) paint/invalidation/svg/js-update-style.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-update-transform-addition.svg [ Failure ]
 Bug(none) paint/invalidation/svg/js-update-transform-changes.svg [ Failure ]
-Bug(none) paint/invalidation/svg/marker-child-changes-css.svg [ Failure ]
-Bug(none) paint/invalidation/svg/marker-child-changes.svg [ Failure ]
 Bug(none) paint/invalidation/svg/marker-strokeWidth-changes.svg [ Failure ]
 Bug(none) paint/invalidation/svg/marker-viewBox-changes.svg [ Failure ]
 Bug(none) paint/invalidation/svg/mask-child-changes.svg [ Failure ]
@@ -1459,7 +1454,6 @@
 Bug(none) paint/invalidation/svg/object-sizing-no-width-height-change-content-box-size.xhtml [ Failure ]
 Bug(none) paint/invalidation/svg/outline-offset-text.html [ Failure ]
 Bug(none) paint/invalidation/svg/paintorder-filtered.svg [ Failure ]
-Bug(none) paint/invalidation/svg/path-pathlength-change.html [ Failure ]
 Bug(none) paint/invalidation/svg/relative-sized-content-with-resources.xhtml [ Failure ]
 Bug(none) paint/invalidation/svg/relative-sized-content.xhtml [ Failure ]
 Bug(none) paint/invalidation/svg/relative-sized-deep-shadow-tree-content.xhtml [ Failure ]
@@ -1480,7 +1474,6 @@
 Bug(none) paint/invalidation/svg/repaint-non-scaling-stroke-text.html [ Failure ]
 Bug(none) paint/invalidation/svg/repaint-on-image-bounds-change.svg [ Failure ]
 Bug(none) paint/invalidation/svg/repaint-paintorder.svg [ Failure ]
-Bug(none) paint/invalidation/svg/repaint-stroke-width-changes.svg [ Failure ]
 Bug(none) paint/invalidation/svg/resize-svg-invalidate-children-2.html [ Failure ]
 Bug(none) paint/invalidation/svg/resize-svg-invalidate-children.html [ Failure ]
 Bug(none) paint/invalidation/svg/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ]
@@ -1559,7 +1552,6 @@
 Bug(none) paint/invalidation/textarea-appearance-none-resize-handle.html [ Failure ]
 Bug(none) paint/invalidation/textarea-caret.html [ Failure ]
 Bug(none) paint/invalidation/textarea-resize-property-change.html [ Failure ]
-Bug(none) paint/invalidation/textarea-set-disabled.html [ Failure ]
 Bug(none) paint/invalidation/transform-absolute-child.html [ Failure ]
 Bug(none) paint/invalidation/transform-absolute-in-positioned-container.html [ Failure ]
 Bug(none) paint/invalidation/transform-disable-layoutstate.html [ Failure ]
@@ -2023,8 +2015,6 @@
 crbug.com/589265 virtual/threaded/animations/animated-filter-svg-element.html [ Failure Crash ]
 
 # Some work remains to fully support composited animation and scrolling.
-Bug(none) virtual/threaded/animations/css-animation-affects-use-elements.html [ Timeout Failure ]
-Bug(none) virtual/threaded/animations/composited-animation-style-update.html [ Timeout Failure ]
 crbug.com/702350 transitions/opacity-transform-transitions-inside-iframe.html [ Timeout ]
 crbug.com/702350 virtual/threaded/transitions/opacity-transform-transitions-inside-iframe.html [ Timeout ]
 crbug.com/702353 transitions/transition-end-event-destroy-iframe.html [ Timeout ]
@@ -2039,7 +2029,6 @@
 
 Bug(none) virtual/threaded/animations/3d/change-transform-in-end-event.html [ Failure ]
 Bug(none) virtual/threaded/animations/composited-pseudo-element-animation.html [ Failure ]
-Bug(none) virtual/threaded/animations/css-composite-animation-affects-use-elements.html [ Failure ]
 Bug(none) virtual/threaded/transitions/transition-end-event-rendering.html [ Failure ]
 Bug(none) virtual/threaded/animations/svg-attribute-composition/svg-startOffset-composition.html [ Failure ]
 
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index 8ca7c22e..c5aebf72 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -498,5 +498,10 @@
     "prefix": "new-remote-playback-pipeline",
     "base": "external/wpt/remote-playback",
     "args": ["--enable-features=NewRemotePlaybackPipeline"]
+  },
+  {
+    "prefix": "high-contrast-mode",
+    "base": "paint/high-contrast-mode",
+    "args": ["--blink-settings=highContrastMode=3"]
   }
 ]
diff --git a/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds-expected.png b/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..b0299df
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds-expected.txt b/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds-expected.txt
new file mode 100644
index 0000000..3e4215d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds-expected.txt
@@ -0,0 +1,4 @@
+Red on white  Green on white  Blue on white
+Red on black  Green on black  Blue on black
+Black on red  Black on green  Black on blue
+White on red  White on green  White on blue
diff --git a/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds.html b/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds.html
new file mode 100644
index 0000000..069dd5d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/high-contrast-mode/text-on-backgrounds.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<script>
+  if (window.testRunner)
+    testRunner.dumpAsTextWithPixelResults();
+</script>
+<style>
+  .block {
+    font-family: Ahem;
+    font-size: 20px;
+    width: 200px;
+    height: 100px;
+    display: inline-block;
+    margin: 10px;
+    padding: 10px;
+    border: 1px solid #000;
+  }
+</style>
+<div>
+  <div class="block" style="color: #a00;">
+    Red on white
+  </div>
+  <div class="block" style="color: #0a0;">
+    Green on white
+  </div>
+  <div class="block" style="color: #00a;">
+    Blue on white
+  </div>
+</div>
+<div>
+  <div class="block" style="color: #f99; background-color: #000;">
+    Red on black
+  </div>
+  <div class="block" style="color: #9f9; background-color: #000;">
+    Green on black
+  </div>
+  <div class="block" style="color: #99f; background-color: #000;">
+    Blue on black
+  </div>
+</div>
+<div>
+  <div class="block" style="color: #000; background-color: #fdd;">
+    Black on red
+  </div>
+  <div class="block" style="color: #000; background-color: #dfd;">
+    Black on green
+  </div>
+  <div class="block" style="color: #000; background-color: #ddf;">
+    Black on blue
+  </div>
+</div>
+<div>
+  <div class="block" style="color: #fff; background-color: #600;">
+    White on red
+  </div>
+  <div class="block" style="color: #fff; background-color: #060;">
+    White on green
+  </div>
+  <div class="block" style="color: #fff; background-color: #006;">
+    White on blue
+  </div>
+</div>
diff --git a/third_party/WebKit/LayoutTests/plugins/request-low-latency-touch.html b/third_party/WebKit/LayoutTests/plugins/request-low-latency-touch.html
new file mode 100644
index 0000000..c9874bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/plugins/request-low-latency-touch.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<body>
+<embed id="touch_plugin" type="application/x-webkit-test-webplugin" accepts-touch="raw-lowlatency"></embed>
+<script>
+
+test(function() {
+    // ensure layout is valid.
+    touch_plugin.offsetLeft;
+
+    assert_equals(window.internals.touchStartOrMoveEventHandlerCount(document), 1, "One touch event handler registered.");
+}, "raw handler added");
+
+</script>
+</body>
diff --git a/third_party/WebKit/LayoutTests/virtual/high-contrast-mode/paint/high-contrast-mode/README.txt b/third_party/WebKit/LayoutTests/virtual/high-contrast-mode/paint/high-contrast-mode/README.txt
new file mode 100644
index 0000000..c351a618
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/high-contrast-mode/paint/high-contrast-mode/README.txt
@@ -0,0 +1,3 @@
+# This suite runs the tests in LayoutTests/paint/high-contrast-mode
+# with --blink-settings="highContrastMode=3"
+# See the virtual_test_suites() method in Tools/Scripts/webkitpy/layout_tests/port/base.py.
diff --git a/third_party/WebKit/LayoutTests/virtual/high-contrast-mode/paint/high-contrast-mode/text-on-backgrounds-expected.png b/third_party/WebKit/LayoutTests/virtual/high-contrast-mode/paint/high-contrast-mode/text-on-backgrounds-expected.png
new file mode 100644
index 0000000..b1d9d7c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/high-contrast-mode/paint/high-contrast-mode/text-on-backgrounds-expected.png
Binary files differ
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
index 902073e..23ab64e 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -43,6 +43,7 @@
 #include "core/editing/commands/TypingCommand.h"
 #include "core/editing/iterators/CharacterIterator.h"
 #include "core/editing/markers/DocumentMarkerController.h"
+#include "core/editing/markers/SpellCheckMarker.h"
 #include "core/editing/spellcheck/IdleSpellCheckCallback.h"
 #include "core/editing/spellcheck/SpellCheckRequester.h"
 #include "core/editing/spellcheck/SpellCheckerClient.h"
@@ -91,6 +92,45 @@
       .Build();
 }
 
+EphemeralRange ExpandSelectionRangeIfNecessary(
+    const VisibleSelection& selection) {
+  DCHECK(!selection.IsNone());
+
+  // If some text is actually selected, we can use the selection range as-is to
+  // check for a marker. If no text is selected (we just have a caret
+  // somewhere), we need to expand one character on either side so we can find
+  // a spelling marker immediately before or after the caret.
+
+  // (The spelling markers on these words may be anchored to a different node
+  // than the collapsed selection's Position is, but once we expand the
+  // selection, if we're next to a marker, either the start or end point should
+  // now be anchored relative to the same text node as that marker.)
+
+  // Some text is actually selected
+  if (selection.IsRange())
+    return EphemeralRange(selection.Start(), selection.End());
+
+  // No text is actually selected, need to expand the selection range. This is
+  // to make sure we can find a marker touching the caret. E.g. if we have:
+  // <span>word1 <b>word2</b></span>
+  // with a caret selection immediately before "word2", there's one text node
+  // immediately before the caret ("word1 ") and one immediately after
+  // ("word2"). Expanding the selection by one character on either side ensures
+  // we get a range that intersects both neighboring text nodes (if they exist).
+  const VisiblePosition& caret_position = selection.VisibleStart();
+
+  const Position& previous_position =
+      PreviousPositionOf(caret_position).DeepEquivalent();
+
+  const Position& next_position =
+      NextPositionOf(caret_position).DeepEquivalent();
+
+  return EphemeralRange(
+      previous_position.IsNull() ? caret_position.DeepEquivalent()
+                                 : previous_position,
+      next_position.IsNull() ? caret_position.DeepEquivalent() : next_position);
+}
+
 }  // namespace
 
 SpellChecker* SpellChecker::Create(LocalFrame& frame) {
@@ -811,51 +851,57 @@
   }
 }
 
+Optional<std::pair<Node*, SpellCheckMarker*>>
+SpellChecker::GetSpellCheckMarkerTouchingSelection() {
+  const VisibleSelection& selection =
+      GetFrame().Selection().ComputeVisibleSelectionInDOMTree();
+  if (selection.IsNone())
+    return Optional<std::pair<Node*, SpellCheckMarker*>>();
+
+  const EphemeralRange& range_to_check =
+      ExpandSelectionRangeIfNecessary(selection);
+
+  Node* const start_container =
+      range_to_check.StartPosition().ComputeContainerNode();
+  const unsigned start_offset =
+      range_to_check.StartPosition().ComputeOffsetInContainerNode();
+  Node* const end_container =
+      range_to_check.EndPosition().ComputeContainerNode();
+  const unsigned end_offset =
+      range_to_check.EndPosition().ComputeOffsetInContainerNode();
+
+  for (Node& node : range_to_check.Nodes()) {
+    const DocumentMarkerVector& markers_in_node =
+        GetFrame().GetDocument()->Markers().MarkersFor(
+            &node, DocumentMarker::MisspellingMarkers());
+    for (DocumentMarker* marker : markers_in_node) {
+      if (node == start_container && marker->EndOffset() <= start_offset)
+        continue;
+      if (node == end_container && marker->StartOffset() >= end_offset)
+        continue;
+
+      return std::make_pair(&node, &ToSpellCheckMarker(*marker));
+    }
+  }
+
+  // No marker found
+  return Optional<std::pair<Node*, SpellCheckMarker*>>();
+}
+
 void SpellChecker::ReplaceMisspelledRange(const String& text) {
-  EphemeralRange caret_range = GetFrame()
-                                   .Selection()
-                                   .ComputeVisibleSelectionInDOMTree()
-                                   .ToNormalizedEphemeralRange();
-  if (caret_range.IsNull())
+  const Optional<std::pair<Node*, SpellCheckMarker*>>& node_and_marker =
+      GetSpellCheckMarkerTouchingSelection();
+  if (!node_and_marker)
     return;
 
-  Node* const caret_start_container =
-      caret_range.StartPosition().ComputeContainerNode();
-  Node* const caret_end_container =
-      caret_range.EndPosition().ComputeContainerNode();
-
-  // We don't currently support the case where a misspelling spans multiple
-  // nodes
-  if (caret_start_container != caret_end_container)
-    return;
-
-  const unsigned caret_start_offset =
-      caret_range.StartPosition().ComputeOffsetInContainerNode();
-  const unsigned caret_end_offset =
-      caret_range.EndPosition().ComputeOffsetInContainerNode();
-
-  const DocumentMarkerVector& markers_in_node =
-      GetFrame().GetDocument()->Markers().MarkersFor(
-          caret_start_container, DocumentMarker::MisspellingMarkers());
-
-  const auto marker_it =
-      std::find_if(markers_in_node.begin(), markers_in_node.end(),
-                   [=](const DocumentMarker* marker) {
-                     return marker->StartOffset() < caret_end_offset &&
-                            marker->EndOffset() > caret_start_offset;
-                   });
-  if (marker_it == markers_in_node.end())
-    return;
-
-  const DocumentMarker* found_marker = *marker_it;
-  EphemeralRange marker_range = EphemeralRange(
-      Position(caret_start_container, found_marker->StartOffset()),
-      Position(caret_start_container, found_marker->EndOffset()));
-  if (marker_range.IsNull())
-    return;
+  Node* const container_node = node_and_marker.value().first;
+  const SpellCheckMarker* const marker = node_and_marker.value().second;
 
   GetFrame().Selection().SetSelection(
-      SelectionInDOMTree::Builder().SetBaseAndExtent(marker_range).Build());
+      SelectionInDOMTree::Builder()
+          .Collapse(Position(container_node, marker->StartOffset()))
+          .Extend(Position(container_node, marker->EndOffset()))
+          .Build());
 
   Document& current_document = *GetFrame().GetDocument();
 
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
index 371f354..0dab20ae 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h
@@ -40,6 +40,7 @@
 class LocalFrame;
 class ReplaceSelectionCommand;
 class SpellCheckerClient;
+class SpellCheckMarker;
 class SpellCheckRequest;
 class SpellCheckRequester;
 class TextCheckerClient;
@@ -72,6 +73,8 @@
   void RespondToChangedContents();
   void RespondToChangedSelection(const Position& old_selection_start,
                                  FrameSelection::SetSelectionOptions);
+  Optional<std::pair<Node*, SpellCheckMarker*>>
+  GetSpellCheckMarkerTouchingSelection();
   void ReplaceMisspelledRange(const String&);
   void RemoveSpellingMarkers();
   void RemoveSpellingMarkersUnderWords(const Vector<String>& words);
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
index ec53a09..f950f5c 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellCheckerTest.cpp
@@ -129,4 +129,254 @@
       ToSpellCheckMarker(GetDocument().Markers().Markers()[0])->Description());
 }
 
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_FirstCharSelected) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "spllchck"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 8)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 0), Position(text, 1))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_LastCharSelected) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "spllchck"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 8)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 7), Position(text, 8))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_SingleCharWordSelected) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "s"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 1)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 0), Position(text, 1))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretLeftOfSingleCharWord) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "s"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 1)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretRightOfSingleCharWord) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "s"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 1)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 1), Position(text, 1))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretLeftOfMultiCharWord) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "spllchck"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 8)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretRightOfMultiCharWord) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "spllchck"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 8)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 8), Position(text, 8))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretMiddleOfWord) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "spllchck"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 8)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 4), Position(text, 4))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_TRUE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretOneCharLeftOfMisspelling) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "a spllchck"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 2), Position(text, 10)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 1), Position(text, 1))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_FALSE(result);
+}
+
+TEST_F(SpellCheckerTest,
+       GetSpellCheckMarkerTouchingSelection_CaretOneCharRightOfMisspelling) {
+  SetBodyContent(
+      "<div contenteditable>"
+      "spllchck a"
+      "</div>");
+  Element* div = GetDocument().QuerySelector("div");
+  Node* text = div->firstChild();
+
+  GetDocument().Markers().AddSpellingMarker(
+      EphemeralRange(Position(text, 0), Position(text, 8)));
+
+  GetDocument().GetFrame()->Selection().SetSelection(
+      SelectionInDOMTree::Builder()
+          .SetBaseAndExtent(Position(text, 9), Position(text, 9))
+          .Build());
+
+  Optional<std::pair<Node*, SpellCheckMarker*>> result =
+      GetDocument()
+          .GetFrame()
+          ->GetSpellChecker()
+          .GetSpellCheckMarkerTouchingSelection();
+  EXPECT_FALSE(result);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
index 05febfd..effbd781 100644
--- a/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
+++ b/third_party/WebKit/Source/core/exported/WebPluginContainerImpl.cpp
@@ -546,14 +546,31 @@
 
   if (Page* page = element_->GetDocument().GetPage()) {
     EventHandlerRegistry& registry = page->GetEventHandlerRegistry();
-    if (request_type != kTouchEventRequestTypeNone &&
-        touch_event_request_type_ == kTouchEventRequestTypeNone) {
+    if (request_type == kTouchEventRequestTypeRawLowLatency) {
+      if (touch_event_request_type_ != kTouchEventRequestTypeNone) {
+        registry.DidRemoveEventHandler(
+            *element_, EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
+      }
       registry.DidAddEventHandler(
-          *element_, EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
-    } else if (request_type == kTouchEventRequestTypeNone &&
-               touch_event_request_type_ != kTouchEventRequestTypeNone) {
+          *element_,
+          EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency);
+    } else if (request_type != kTouchEventRequestTypeNone) {
+      if (touch_event_request_type_ == kTouchEventRequestTypeRawLowLatency) {
+        registry.DidRemoveEventHandler(
+            *element_,
+            EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency);
+      }
+      if (touch_event_request_type_ == kTouchEventRequestTypeNone ||
+          touch_event_request_type_ == kTouchEventRequestTypeRawLowLatency) {
+        registry.DidAddEventHandler(
+            *element_, EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
+      }
+    } else if (touch_event_request_type_ != kTouchEventRequestTypeNone) {
       registry.DidRemoveEventHandler(
-          *element_, EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
+          *element_,
+          touch_event_request_type_ == kTouchEventRequestTypeRawLowLatency
+              ? EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency
+              : EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
     }
   }
   touch_event_request_type_ = request_type;
@@ -866,7 +883,8 @@
   switch (touch_event_request_type_) {
     case kTouchEventRequestTypeNone:
       return;
-    case kTouchEventRequestTypeRaw: {
+    case kTouchEventRequestTypeRaw:
+    case kTouchEventRequestTypeRawLowLatency: {
       if (!event->NativeEvent())
         return;
 
diff --git a/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp b/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp
index 1a6fa11..382cee3 100644
--- a/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp
+++ b/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp
@@ -243,13 +243,18 @@
           GetWebEventListenerProperties(HasEventHandlers(kWheelEventBlocking),
                                         HasEventHandlers(kWheelEventPassive)));
       break;
+    case kTouchStartOrMoveEventBlockingLowLatency:
+      page_->GetChromeClient().SetNeedsLowLatencyInput(frame,
+                                                       has_active_handlers);
+    // Fall through.
     case kTouchStartOrMoveEventBlocking:
     case kTouchStartOrMoveEventPassive:
     case kPointerEvent:
       page_->GetChromeClient().SetEventListenerProperties(
           frame, WebEventListenerClass::kTouchStartOrMove,
           GetWebEventListenerProperties(
-              HasEventHandlers(kTouchStartOrMoveEventBlocking),
+              HasEventHandlers(kTouchStartOrMoveEventBlocking) ||
+                  HasEventHandlers(kTouchStartOrMoveEventBlockingLowLatency),
               HasEventHandlers(kTouchStartOrMoveEventPassive) ||
                   HasEventHandlers(kPointerEvent)));
       break;
@@ -275,8 +280,11 @@
     EventHandlerClass handler_class) {
   ScrollingCoordinator* scrolling_coordinator =
       page_->GetScrollingCoordinator();
-  if (scrolling_coordinator && handler_class == kTouchStartOrMoveEventBlocking)
+  if (scrolling_coordinator &&
+      (handler_class == kTouchStartOrMoveEventBlocking ||
+       handler_class == kTouchStartOrMoveEventBlockingLowLatency)) {
     scrolling_coordinator->TouchEventTargetRectsDidChange();
+  }
 }
 
 DEFINE_TRACE(EventHandlerRegistry) {
diff --git a/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h b/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h
index 4c4d2bb2..4d48831 100644
--- a/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h
+++ b/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h
@@ -33,6 +33,7 @@
     kWheelEventBlocking,
     kWheelEventPassive,
     kTouchStartOrMoveEventBlocking,
+    kTouchStartOrMoveEventBlockingLowLatency,
     kTouchStartOrMoveEventPassive,
     kTouchEndOrCancelEventBlocking,
     kTouchEndOrCancelEventPassive,
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
index 25fd42f..02833ce9 100644
--- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -3278,6 +3278,15 @@
       GraphicsContext graphics_context(*paint_controller_);
       if (RuntimeEnabledFeatures::PrintBrowserEnabled())
         graphics_context.SetPrinting(true);
+
+      if (Settings* settings = frame_->GetSettings()) {
+        HighContrastSettings high_contrast_settings;
+        high_contrast_settings.mode = settings->GetHighContrastMode();
+        high_contrast_settings.grayscale = settings->GetHighContrastGrayscale();
+        high_contrast_settings.contrast = settings->GetHighContrastContrast();
+        graphics_context.SetHighContrast(high_contrast_settings);
+      }
+
       Paint(graphics_context, CullRect(LayoutRect::InfiniteIntRect()));
       paint_controller_->CommitNewDisplayItems();
     }
@@ -5038,8 +5047,10 @@
 
   bool has_handlers =
       frame_->GetPage() &&
-      frame_->GetPage()->GetEventHandlerRegistry().HasEventHandlers(
-          EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
+      (frame_->GetPage()->GetEventHandlerRegistry().HasEventHandlers(
+           EventHandlerRegistry::kTouchStartOrMoveEventBlocking) ||
+       frame_->GetPage()->GetEventHandlerRegistry().HasEventHandlers(
+           EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency));
   if (was_throttled != CanThrottleRendering() && scrolling_coordinator &&
       has_handlers)
     scrolling_coordinator->TouchEventTargetRectsDidChange();
diff --git a/third_party/WebKit/Source/core/frame/Settings.h b/third_party/WebKit/Source/core/frame/Settings.h
index 55a365e..546e718 100644
--- a/third_party/WebKit/Source/core/frame/Settings.h
+++ b/third_party/WebKit/Source/core/frame/Settings.h
@@ -43,6 +43,7 @@
 #include "platform/Timer.h"
 #include "platform/fonts/GenericFontFamilySettings.h"
 #include "platform/geometry/IntSize.h"
+#include "platform/graphics/HighContrastSettings.h"
 #include "platform/graphics/ImageAnimationPolicy.h"
 #include "platform/weborigin/KURL.h"
 #include "public/platform/PointerProperties.h"
diff --git a/third_party/WebKit/Source/core/frame/Settings.json5 b/third_party/WebKit/Source/core/frame/Settings.json5
index a45cdb29..798ae0f 100644
--- a/third_party/WebKit/Source/core/frame/Settings.json5
+++ b/third_party/WebKit/Source/core/frame/Settings.json5
@@ -931,5 +931,23 @@
       type: "AutoplayPolicy::Type",
       initial: "AutoplayPolicy::Type::kNoUserGestureRequired",
     },
+
+    //
+    // High contrast mode
+    //
+    {
+      name: "highContrastMode",
+      initial: "HighContrastMode::kOff",
+      type: "HighContrastMode",
+    },
+    {
+      name: "highContrastGrayscale",
+      initial: false,
+    },
+    {
+      name: "highContrastContrast",
+      initial: 0,
+      type: "double",
+    }
   ],
 }
diff --git a/third_party/WebKit/Source/core/input/TouchEventManager.cpp b/third_party/WebKit/Source/core/input/TouchEventManager.cpp
index 6f6476f..ccd42f0 100644
--- a/third_party/WebKit/Source/core/input/TouchEventManager.cpp
+++ b/third_party/WebKit/Source/core/input/TouchEventManager.cpp
@@ -30,6 +30,8 @@
   return registry.HasEventHandlers(
              EventHandlerRegistry::kTouchStartOrMoveEventBlocking) ||
          registry.HasEventHandlers(
+             EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency) ||
+         registry.HasEventHandlers(
              EventHandlerRegistry::kTouchStartOrMoveEventPassive) ||
          registry.HasEventHandlers(
              EventHandlerRegistry::kTouchEndOrCancelEventBlocking) ||
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index abd711d..47f4f2a 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -3066,6 +3066,13 @@
       paint_info.paint_layer->GetLayoutObject().GetFrame());
   context.SetDeviceScaleFactor(device_scale_factor);
 
+  Settings* settings = GetLayoutObject().GetFrame()->GetSettings();
+  HighContrastSettings high_contrast_settings;
+  high_contrast_settings.mode = settings->GetHighContrastMode();
+  high_contrast_settings.grayscale = settings->GetHighContrastGrayscale();
+  high_contrast_settings.contrast = settings->GetHighContrastContrast();
+  context.SetHighContrast(high_contrast_settings);
+
   if (paint_info.paint_layer->GetCompositingState() !=
       kPaintsIntoGroupedBacking) {
     // FIXME: GraphicsLayers need a way to split for multicol.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index 2c56634..8d088bf 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -150,6 +150,44 @@
   return layout_opp_iter_.get();
 }
 
+bool NGConstraintSpace::operator==(const NGConstraintSpace& other) const {
+  // TODO(cbiesinger): For simplicity and performance, for now, we only
+  // consider two constraint spaces equal if neither one has unpositioned
+  // floats. We should consider changing this in the future.
+  if (unpositioned_floats_.size() || other.unpositioned_floats_.size())
+    return false;
+
+  if (exclusions_ && other.exclusions_ && *exclusions_ != *other.exclusions_)
+    return false;
+
+  return available_size_ == other.available_size_ &&
+         percentage_resolution_size_ == other.percentage_resolution_size_ &&
+         initial_containing_block_size_ ==
+             other.initial_containing_block_size_ &&
+         fragmentainer_space_available_ ==
+             other.fragmentainer_space_available_ &&
+         is_fixed_size_inline_ == other.is_fixed_size_inline_ &&
+         is_fixed_size_block_ == other.is_fixed_size_block_ &&
+         is_shrink_to_fit_ == other.is_shrink_to_fit_ &&
+         is_inline_direction_triggers_scrollbar_ ==
+             other.is_inline_direction_triggers_scrollbar_ &&
+         is_block_direction_triggers_scrollbar_ ==
+             other.is_block_direction_triggers_scrollbar_ &&
+         block_direction_fragmentation_type_ ==
+             other.block_direction_fragmentation_type_ &&
+         is_new_fc_ == other.is_new_fc_ &&
+         is_anonymous_ == other.is_anonymous_ &&
+         writing_mode_ == other.writing_mode_ &&
+         direction_ == other.direction_ &&
+         margin_strut_ == other.margin_strut_ &&
+         bfc_offset_ == other.bfc_offset_ &&
+         clearance_offset_ == other.clearance_offset_;
+}
+
+bool NGConstraintSpace::operator!=(const NGConstraintSpace& other) const {
+  return !(*this == other);
+}
+
 String NGConstraintSpace::ToString() const {
   return String::Format(
       "Offset: %s,%s Size: %sx%s MarginStrut: %s"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index 062dd179..119b9a4 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -133,6 +133,9 @@
     return clearance_offset_;
   }
 
+  bool operator==(const NGConstraintSpace&) const;
+  bool operator!=(const NGConstraintSpace&) const;
+
   String ToString() const;
 
  private:
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc
index 61ea162..444e00eb 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.cc
@@ -75,4 +75,14 @@
   return *this;
 }
 
+bool NGExclusions::operator==(const NGExclusions& other) const {
+  if (storage.size() != other.storage.size())
+    return false;
+  for (size_t i = 0; i < storage.size(); ++i) {
+    if (*storage[i] != *other.storage[i])
+      return false;
+  }
+  return true;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h
index 860721ce..9466dfb 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_exclusion.h
@@ -31,6 +31,7 @@
   Type type = kExclusionTypeUndefined;
 
   bool operator==(const NGExclusion& other) const;
+  bool operator!=(const NGExclusion& other) const { return !(*this == other); }
 
   String ToString() const;
 
@@ -66,6 +67,8 @@
   const NGExclusion* last_right_float;  // Owned by storage.
 
   NGExclusions& operator=(const NGExclusions& other);
+  bool operator==(const NGExclusions& other) const;
+  bool operator!=(const NGExclusions& other) const { return !(*this == other); }
 
   void Add(const NGExclusion& exclusion);
 };
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h
index 1fbd94c..2613581 100644
--- a/third_party/WebKit/Source/core/loader/EmptyClients.h
+++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -203,7 +203,7 @@
   }
   void UpdateEventRectsForSubframeIfNecessary(LocalFrame* frame) override {}
   void SetHasScrollEventHandlers(LocalFrame*, bool) override {}
-
+  void SetNeedsLowLatencyInput(LocalFrame*, bool) override {}
   void SetTouchAction(LocalFrame*, TouchAction) override {}
 
   void DidAssociateFormControlsAfterLoad(LocalFrame*) override {}
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h
index 215af09..8fc0f0aa 100644
--- a/third_party/WebKit/Source/core/page/ChromeClient.h
+++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -265,6 +265,7 @@
       WebEventListenerClass) const = 0;
   virtual void UpdateEventRectsForSubframeIfNecessary(LocalFrame*) = 0;
   virtual void SetHasScrollEventHandlers(LocalFrame*, bool) = 0;
+  virtual void SetNeedsLowLatencyInput(LocalFrame*, bool) = 0;
   virtual const WebInputEvent* GetCurrentInputEvent() const { return nullptr; }
 
   virtual void SetTouchAction(LocalFrame*, TouchAction) = 0;
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index b1e505d5..2e4683b 100644
--- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -1041,12 +1041,14 @@
   return should_handle_scroll_gesture_on_main_thread_region;
 }
 
-static void AccumulateDocumentTouchEventTargetRects(LayerHitTestRects& rects,
-                                                    const Document* document) {
+static void AccumulateDocumentTouchEventTargetRects(
+    LayerHitTestRects& rects,
+    EventHandlerRegistry::EventHandlerClass event_class,
+    const Document* document) {
   DCHECK(document);
   const EventTargetSet* targets =
       document->GetPage()->GetEventHandlerRegistry().EventHandlerTargets(
-          EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
+          event_class);
   if (!targets)
     return;
 
@@ -1099,7 +1101,8 @@
       continue;
 
     if (node->IsDocumentNode() && node != document) {
-      AccumulateDocumentTouchEventTargetRects(rects, ToDocument(node));
+      AccumulateDocumentTouchEventTargetRects(rects, event_class,
+                                              ToDocument(node));
     } else if (LayoutObject* layout_object = node->GetLayoutObject()) {
       // If the set also contains one of our ancestor nodes then processing
       // this node would be redundant.
@@ -1143,7 +1146,11 @@
   if (!document || !document->View())
     return;
 
-  AccumulateDocumentTouchEventTargetRects(rects, document);
+  AccumulateDocumentTouchEventTargetRects(
+      rects, EventHandlerRegistry::kTouchStartOrMoveEventBlocking, document);
+  AccumulateDocumentTouchEventTargetRects(
+      rects, EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency,
+      document);
 }
 
 void ScrollingCoordinator::
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 563ee83..29bcc17 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -544,7 +544,7 @@
     IncludeScrollbarsInRect scrollbar_inclusion) const {
   int vertical_scrollbar_width = 0;
   int horizontal_scrollbar_height = 0;
-  if (scrollbar_inclusion == kIncludeScrollbars) {
+  if (scrollbar_inclusion == kExcludeScrollbars) {
     vertical_scrollbar_width =
         (VerticalScrollbar() && !VerticalScrollbar()->IsOverlayScrollbar())
             ? VerticalScrollbar()->ScrollbarThickness()
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
index a4b0855..84399a0 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
@@ -96,14 +96,10 @@
   PaintPropertyTreeBuilderContext()
       : container_for_absolute_position(nullptr),
         force_subtree_update(false)
-#if DCHECK_IS_ON()
-        ,
-        is_actually_needed(true)
-#endif
   {
   }
 
-  Vector<PaintPropertyTreeBuilderFragmentContext> fragments;
+  Vector<PaintPropertyTreeBuilderFragmentContext, 1> fragments;
   const LayoutObject* container_for_absolute_position;
 
   // True if a change has forced all properties in a subtree to be updated. This
@@ -114,7 +110,7 @@
 #if DCHECK_IS_ON()
   // When DCHECK_IS_ON() we create PaintPropertyTreeBuilderContext even if not
   // needed. See FindPaintOffsetAndVisualRectNeedingUpdate.h.
-  bool is_actually_needed;
+  bool is_actually_needed = true;
 #endif
 };
 
diff --git a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
index cd0628b..9203531 100644
--- a/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
+++ b/third_party/WebKit/Source/core/paint/RoundedInnerRectClipper.cpp
@@ -76,10 +76,9 @@
         layout_object, clip_type_, LayoutRect::InfiniteIntRect(),
         rounded_rect_clips);
   } else {
-    ClipDisplayItem clip_display_item(layout_object, clip_type_,
-                                      LayoutRect::InfiniteIntRect(),
-                                      rounded_rect_clips);
-    clip_display_item.Replay(paint_info.context);
+    paint_info.context.Save();
+    for (const auto& rrect : rounded_rect_clips)
+      paint_info.context.ClipRoundedRect(rrect);
   }
 }
 
@@ -92,8 +91,7 @@
     paint_info_.context.GetPaintController().EndItem<EndClipDisplayItem>(
         layout_object_, end_type);
   } else {
-    EndClipDisplayItem end_clip_display_item(layout_object_, end_type);
-    end_clip_display_item.Replay(paint_info_.context);
+    paint_info_.context.Restore();
   }
 }
 
diff --git a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
index e8fe44a9..4831db9 100644
--- a/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/ScrollableAreaPainter.cpp
@@ -171,8 +171,9 @@
   if (painting_overlay_controls && !GetScrollableArea().HasOverlayScrollbars())
     return;
 
-  IntRect clip_rect(adjusted_paint_offset,
-                    GetScrollableArea().VisibleContentRect().Size());
+  IntRect clip_rect(
+      adjusted_paint_offset,
+      GetScrollableArea().VisibleContentRect(kIncludeScrollbars).Size());
   ClipRecorder clip_recorder(context, GetScrollableArea().Box(),
                              DisplayItem::kClipLayerOverflowControls,
                              clip_rect);
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp
index c426823..a05e0b2 100644
--- a/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -1658,6 +1658,9 @@
   DCHECK(document);
   return EventHandlerCount(
              *document, EventHandlerRegistry::kTouchStartOrMoveEventBlocking) +
+         EventHandlerCount(
+             *document,
+             EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency) +
          EventHandlerCount(*document,
                            EventHandlerRegistry::kTouchStartOrMoveEventPassive);
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/Tests.js b/third_party/WebKit/Source/devtools/front_end/Tests.js
index 91d725f..2d86887 100644
--- a/third_party/WebKit/Source/devtools/front_end/Tests.js
+++ b/third_party/WebKit/Source/devtools/front_end/Tests.js
@@ -662,6 +662,61 @@
     step1();
   };
 
+  TestSuite.prototype.testDispatchKeyEventShowsAutoFill = function() {
+    var test = this;
+    var receivedReady = false;
+
+    function signalToShowAutofill() {
+      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
+          {type: 'rawKeyDown', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
+      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
+          {type: 'keyUp', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
+    }
+
+    function selectTopAutoFill() {
+      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
+          {type: 'rawKeyDown', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
+      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
+          {type: 'keyUp', key: 'Down', windowsVirtualKeyCode: 40, nativeVirtualKeyCode: 40});
+      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
+          {type: 'rawKeyDown', key: 'Enter', windowsVirtualKeyCode: 13, nativeVirtualKeyCode: 13});
+      SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
+          {type: 'keyUp', key: 'Enter', windowsVirtualKeyCode: 13, nativeVirtualKeyCode: 13});
+
+      test.evaluateInConsole_('document.getElementById("name").value', onResultOfInput);
+    }
+
+    function onResultOfInput(value) {
+      // Console adds "" around the response.
+      test.assertEquals('"Abbf"', value);
+      test.releaseControl();
+    }
+
+    function onConsoleMessage(event) {
+      var message = event.data.messageText;
+      if (message === 'ready' && !receivedReady) {
+        receivedReady = true;
+        signalToShowAutofill();
+      }
+      // This log comes from the browser unittest code.
+      if (message === 'didShowSuggestions')
+        selectTopAutoFill();
+    }
+
+    this.takeControl();
+
+    // It is possible for the ready console messagage to be already received but not handled
+    // or received later. This ensures we can catch both cases.
+    ConsoleModel.consoleModel.addEventListener(ConsoleModel.ConsoleModel.Events.MessageAdded, onConsoleMessage, this);
+
+    var messages = ConsoleModel.consoleModel.messages();
+    if (messages.length) {
+      var text = messages[0].messageText;
+      this.assertEquals('ready', text);
+      signalToShowAutofill();
+    }
+  };
+
   TestSuite.prototype.testDispatchKeyEventDoesNotCrash = function() {
     SDK.targetManager.mainTarget().inputAgent().invoke_dispatchKeyEvent(
         {type: 'rawKeyDown', windowsVirtualKeyCode: 0x23, key: 'End'});
diff --git a/third_party/WebKit/Source/devtools/scripts/check_gn.js b/third_party/WebKit/Source/devtools/scripts/check_gn.js
index f46e72ca..e942126 100644
--- a/third_party/WebKit/Source/devtools/scripts/check_gn.js
+++ b/third_party/WebKit/Source/devtools/scripts/check_gn.js
@@ -1,6 +1,7 @@
 // Copyright 2017 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+'use strict';
 
 const fs = require('fs');
 const path = require('path');
diff --git a/third_party/WebKit/Source/modules/payments/AndroidPayMethodData.idl b/third_party/WebKit/Source/modules/payments/AndroidPayMethodData.idl
index aa19da9..ad52173b 100644
--- a/third_party/WebKit/Source/modules/payments/AndroidPayMethodData.idl
+++ b/third_party/WebKit/Source/modules/payments/AndroidPayMethodData.idl
@@ -12,4 +12,5 @@
     sequence<DOMString> allowedCardNetworks;
     AndroidPayTokenization paymentMethodTokenizationParameters;
     DOMString minGooglePlayServicesVersion;
+    long apiVersion;
 };
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
index e1fd159..c887b77d 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -346,6 +346,11 @@
     }
   }
 
+  // 0 means the merchant did not specify or it was an invalid value
+  output->api_version = 0;
+  if (android_pay.hasApiVersion())
+    output->api_version = android_pay.apiVersion();
+
   if (android_pay.hasAllowedCardNetworks()) {
     using ::payments::mojom::blink::AndroidPayCardNetwork;
 
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index 0790445..444d9bfa 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -892,6 +892,7 @@
     "graphics/GraphicsTypes.cpp",
     "graphics/GraphicsTypes.h",
     "graphics/GraphicsTypes3D.h",
+    "graphics/HighContrastSettings.h",
     "graphics/Image.cpp",
     "graphics/Image.h",
     "graphics/ImageAnimationPolicy.h",
diff --git a/third_party/WebKit/Source/platform/OWNERS b/third_party/WebKit/Source/platform/OWNERS
index 50537c8..7b7d006 100644
--- a/third_party/WebKit/Source/platform/OWNERS
+++ b/third_party/WebKit/Source/platform/OWNERS
@@ -17,6 +17,7 @@
 thakis@chromium.org
 tkent@chromium.org
 vollick@chromium.org
+wangxianzhu@chromium.org
 
 # In addition to the above, API_OWNERS are also adequate reviewers
 # for adding / changing the status of a feature.
diff --git a/third_party/WebKit/Source/platform/audio/IIRFilter.cpp b/third_party/WebKit/Source/platform/audio/IIRFilter.cpp
index 95433118..7972d976 100644
--- a/third_party/WebKit/Source/platform/audio/IIRFilter.cpp
+++ b/third_party/WebKit/Source/platform/audio/IIRFilter.cpp
@@ -153,7 +153,7 @@
   // The maximum tail time.  This is somewhat arbitrary, but we're assuming that
   // no one is going to expect the IIRFilter to produce an output after this
   // much time after the inputs have stopped.
-  const double kMaxTailTime = 60;
+  const double kMaxTailTime = 10;
 
   // If the maximum amplitude of the impulse response is less than this, we
   // assume that we've reached the tail of the response.  Currently, this means
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
index 9b76631..11df85a 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp
@@ -47,8 +47,10 @@
 #include "third_party/skia/include/core/SkData.h"
 #include "third_party/skia/include/core/SkRRect.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
+#include "third_party/skia/include/effects/SkHighContrastFilter.h"
 #include "third_party/skia/include/effects/SkLumaColorFilter.h"
 #include "third_party/skia/include/effects/SkPictureImageFilter.h"
+#include "third_party/skia/include/effects/SkTableColorFilter.h"
 #include "third_party/skia/include/pathops/SkPathOps.h"
 #include "third_party/skia/include/utils/SkNullCanvas.h"
 
@@ -140,6 +142,38 @@
 }
 #endif
 
+void GraphicsContext::SetHighContrast(const HighContrastSettings& settings) {
+  high_contrast_settings_ = settings;
+
+  SkHighContrastConfig config;
+  switch (high_contrast_settings_.mode) {
+    case HighContrastMode::kOff:
+      high_contrast_filter_.reset(nullptr);
+      return;
+    case HighContrastMode::kSimpleInvertForTesting: {
+      uint8_t identity[256], invert[256];
+      for (int i = 0; i < 256; ++i) {
+        identity[i] = i;
+        invert[i] = 255 - i;
+      }
+      high_contrast_filter_ =
+          SkTableColorFilter::MakeARGB(identity, invert, invert, invert);
+      return;
+    }
+    case HighContrastMode::kInvertBrightness:
+      config.fInvertStyle =
+          SkHighContrastConfig::InvertStyle::kInvertBrightness;
+      break;
+    case HighContrastMode::kInvertLightness:
+      config.fInvertStyle = SkHighContrastConfig::InvertStyle::kInvertLightness;
+      break;
+  }
+
+  config.fGrayscale = high_contrast_settings_.grayscale;
+  config.fContrast = high_contrast_settings_.contrast;
+  high_contrast_filter_ = SkHighContrastFilter::Make(config);
+}
+
 void GraphicsContext::SaveLayer(const SkRect* bounds, const PaintFlags* flags) {
   if (ContextDisabled())
     return;
@@ -351,13 +385,15 @@
 void GraphicsContext::DrawFocusRingPath(const SkPath& path,
                                         const Color& color,
                                         float width) {
-  DrawPlatformFocusRing(path, canvas_, color.Rgb(), width);
+  DrawPlatformFocusRing(path, canvas_, ApplyHighContrastFilter(color).Rgb(),
+                        width);
 }
 
 void GraphicsContext::DrawFocusRingRect(const SkRect& rect,
                                         const Color& color,
                                         float width) {
-  DrawPlatformFocusRing(rect, canvas_, color.Rgb(), width);
+  DrawPlatformFocusRing(rect, canvas_, ApplyHighContrastFilter(color).Rgb(),
+                        width);
 }
 
 void GraphicsContext::DrawFocusRing(const Path& focus_ring_path,
@@ -423,7 +459,7 @@
 }
 
 void GraphicsContext::DrawInnerShadow(const FloatRoundedRect& rect,
-                                      const Color& shadow_color,
+                                      const Color& orig_shadow_color,
                                       const FloatSize& shadow_offset,
                                       float shadow_blur,
                                       float shadow_spread,
@@ -431,6 +467,8 @@
   if (ContextDisabled())
     return;
 
+  Color shadow_color = ApplyHighContrastFilter(orig_shadow_color);
+
   FloatRect hole_rect(rect.Rect());
   hole_rect.Inflate(-shadow_spread);
 
@@ -537,7 +575,8 @@
   }
 
   AdjustLineToPixelBoundaries(p1, p2, width, pen_style);
-  canvas_->drawLine(p1.X(), p1.Y(), p2.X(), p2.Y(), flags);
+  canvas_->drawLine(p1.X(), p1.Y(), p2.X(), p2.Y(),
+                    ApplyHighContrastFilter(&flags));
 }
 
 void GraphicsContext::DrawLineForText(const FloatPoint& pt, float width) {
@@ -614,8 +653,10 @@
   if (ContextDisabled())
     return;
 
-  if (font.DrawText(canvas_, text_info, point, device_scale_factor_, flags))
+  if (font.DrawText(canvas_, text_info, point, device_scale_factor_,
+                    ApplyHighContrastFilter(&flags))) {
     paint_controller_.SetTextPainted();
+  }
 }
 
 void GraphicsContext::DrawText(const Font& font,
@@ -659,7 +700,8 @@
     return;
 
   DrawTextPasses([&font, &text_info, &point, this](const PaintFlags& flags) {
-    if (font.DrawText(canvas_, text_info, point, device_scale_factor_, flags))
+    if (font.DrawText(canvas_, text_info, point, device_scale_factor_,
+                      ApplyHighContrastFilter(&flags)))
       paint_controller_.SetTextPainted();
   });
 }
@@ -687,7 +729,8 @@
   DrawTextPasses(
       [&font, &text_info, &mark, &point, this](const PaintFlags& flags) {
         font.DrawEmphasisMarks(canvas_, text_info, mark, point,
-                               device_scale_factor_, flags);
+                               device_scale_factor_,
+                               ApplyHighContrastFilter(&flags));
       });
 }
 
@@ -717,7 +760,7 @@
                   this](const PaintFlags& flags) {
     if (font.DrawBidiText(canvas_, run_info, point,
                           custom_font_not_ready_action, device_scale_factor_,
-                          flags))
+                          ApplyHighContrastFilter(&flags)))
       paint_controller_.SetTextPainted();
   });
 }
@@ -871,7 +914,7 @@
     return;
   DCHECK(canvas_);
 
-  canvas_->drawOval(oval, flags);
+  canvas_->drawOval(oval, ApplyHighContrastFilter(&flags));
 }
 
 void GraphicsContext::DrawPath(const SkPath& path, const PaintFlags& flags) {
@@ -879,7 +922,7 @@
     return;
   DCHECK(canvas_);
 
-  canvas_->drawPath(path, flags);
+  canvas_->drawPath(path, ApplyHighContrastFilter(&flags));
 }
 
 void GraphicsContext::DrawRect(const SkRect& rect, const PaintFlags& flags) {
@@ -887,7 +930,7 @@
     return;
   DCHECK(canvas_);
 
-  canvas_->drawRect(rect, flags);
+  canvas_->drawRect(rect, ApplyHighContrastFilter(&flags));
 }
 
 void GraphicsContext::DrawRRect(const SkRRect& rrect, const PaintFlags& flags) {
@@ -895,7 +938,7 @@
     return;
   DCHECK(canvas_);
 
-  canvas_->drawRRect(rrect, flags);
+  canvas_->drawRRect(rrect, ApplyHighContrastFilter(&flags));
 }
 
 void GraphicsContext::FillPath(const Path& path_to_fill) {
@@ -1015,7 +1058,7 @@
       canvas_->drawDRRect(outer, inner, ImmutableState()->FillFlags());
     } else {
       PaintFlags flags(ImmutableState()->FillFlags());
-      flags.setColor(color.Rgb());
+      flags.setColor(ApplyHighContrastFilter(color).Rgb());
       canvas_->drawDRRect(outer, inner, flags);
     }
 
@@ -1028,7 +1071,7 @@
   stroke_r_rect.inset(stroke_width / 2, stroke_width / 2);
 
   PaintFlags stroke_flags(ImmutableState()->FillFlags());
-  stroke_flags.setColor(color.Rgb());
+  stroke_flags.setColor(ApplyHighContrastFilter(color).Rgb());
   stroke_flags.setStyle(PaintFlags::kStroke_Style);
   stroke_flags.setStrokeWidth(stroke_width);
 
@@ -1220,7 +1263,7 @@
     return;
 
   PaintFlags flags(ImmutableState()->FillFlags());
-  flags.setColor(color.Rgb());
+  flags.setColor(ApplyHighContrastFilter(color).Rgb());
   canvas_->drawDRRect(SkRRect::MakeRect(rect), rounded_hole_rect, flags);
 }
 
@@ -1277,4 +1320,31 @@
   return nullptr;
 }
 
+Color GraphicsContext::ApplyHighContrastFilter(const Color& input) const {
+  if (!high_contrast_filter_)
+    return input;
+
+  SkColor sk_input =
+      SkColorSetARGB(input.Alpha(), input.Red(), input.Green(), input.Blue());
+  SkColor sk_output = high_contrast_filter_->filterColor(sk_input);
+  return Color(MakeRGBA(SkColorGetR(sk_output), SkColorGetG(sk_output),
+                        SkColorGetB(sk_output), SkColorGetA(sk_output)));
+}
+
+PaintFlags GraphicsContext::ApplyHighContrastFilter(
+    const PaintFlags* input) const {
+  if (input && !high_contrast_filter_)
+    return *input;
+
+  PaintFlags output;
+  if (input)
+    output = *input;
+  if (output.getSkShader()) {
+    output.setColorFilter(high_contrast_filter_);
+  } else {
+    output.setColor(high_contrast_filter_->filterColor(output.getColor()));
+  }
+  return output;
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
index a0cf6f3..5c0725af 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h
@@ -34,6 +34,7 @@
 #include "platform/graphics/DashArray.h"
 #include "platform/graphics/DrawLooperBuilder.h"
 #include "platform/graphics/GraphicsContextState.h"
+#include "platform/graphics/HighContrastSettings.h"
 #include "platform/graphics/ImageOrientation.h"
 #include "platform/graphics/paint/PaintRecord.h"
 #include "platform/graphics/paint/PaintRecorder.h"
@@ -82,6 +83,10 @@
 
   bool ContextDisabled() const { return disabled_state_; }
 
+  const HighContrastSettings& high_contrast_settings() {
+    return high_contrast_settings_;
+  }
+
   // ---------- State management methods -----------------
   void Save();
   void Restore();
@@ -90,6 +95,8 @@
   unsigned SaveCount() const;
 #endif
 
+  void SetHighContrast(const HighContrastSettings&);
+
   float StrokeThickness() const {
     return ImmutableState()->GetStrokeData().Thickness();
   }
@@ -431,6 +438,9 @@
 
   const SkMetaData& MetaData() const { return meta_data_; }
 
+  Color ApplyHighContrastFilter(const Color& input) const;
+  PaintFlags ApplyHighContrastFilter(const PaintFlags* input) const;
+
   // null indicates painting is contextDisabled. Never delete this object.
   PaintCanvas* canvas_;
 
@@ -461,6 +471,9 @@
 
   float device_scale_factor_;
 
+  HighContrastSettings high_contrast_settings_;
+  sk_sp<SkColorFilter> high_contrast_filter_;
+
   unsigned printing_ : 1;
   unsigned has_meta_data_ : 1;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
index 55a61e2..986030a 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsContextTest.cpp
@@ -25,6 +25,7 @@
 
 #include "platform/graphics/GraphicsContext.h"
 
+#include <memory>
 #include "platform/graphics/BitmapImage.h"
 #include "platform/graphics/Path.h"
 #include "platform/graphics/paint/PaintController.h"
@@ -32,11 +33,11 @@
 #include "platform/testing/FontTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "platform/text/TextRun.h"
+#include "platform/wtf/PtrUtil.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkShader.h"
-#include <memory>
 
 namespace blink {
 
@@ -141,4 +142,140 @@
   EXPECT_OPAQUE_PIXELS_IN_RECT(bitmap, IntRect(20, 10, 30, 40));
 }
 
+class GraphicsContextHighConstrastTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    bitmap_.allocN32Pixels(4, 1);
+    bitmap_.eraseColor(0);
+    canvas_ = WTF::WrapUnique(new SkiaPaintCanvas(bitmap_));
+    paint_controller_ = PaintController::Create();
+    context_ = WTF::WrapUnique(new GraphicsContext(*paint_controller_));
+    context_->BeginRecording(FloatRect(0, 0, 4, 1));
+  }
+
+  void DrawColorsToContext() {
+    Color black(0.0f, 0.0f, 0.0f, 1.0f);
+    Color white(1.0f, 1.0f, 1.0f, 1.0f);
+    Color red(1.0f, 0.0f, 0.0f, 1.0f);
+    Color gray(0.5f, 0.5f, 0.5f, 1.0f);
+    context_->FillRect(FloatRect(0, 0, 1, 1), black);
+    context_->FillRect(FloatRect(1, 0, 1, 1), white);
+    context_->FillRect(FloatRect(2, 0, 1, 1), red);
+    context_->FillRect(FloatRect(3, 0, 1, 1), gray);
+    // Capture the result in the bitmap.
+    canvas_->drawPicture(context_->EndRecording());
+  }
+
+  SkBitmap bitmap_;
+  std::unique_ptr<SkiaPaintCanvas> canvas_;
+  std::unique_ptr<PaintController> paint_controller_;
+  std::unique_ptr<GraphicsContext> context_;
+};
+
+// This is just a baseline test, compare against the other variants
+// of the test below, where high contrast mode is enabled.
+TEST_F(GraphicsContextHighConstrastTest, NoHighContrast) {
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xffff0000, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xff808080, *bitmap_.getAddr32(3, 0));
+}
+
+TEST_F(GraphicsContextHighConstrastTest, HighContrastOff) {
+  HighContrastSettings settings;
+  settings.mode = HighContrastMode::kOff;
+  settings.grayscale = false;
+  settings.contrast = 0;
+  context_->SetHighContrast(settings);
+
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xffff0000, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xff808080, *bitmap_.getAddr32(3, 0));
+}
+
+// Simple invert for testing. Each color component |c|
+// is replaced with |255 - c| for easy testing.
+TEST_F(GraphicsContextHighConstrastTest, SimpleInvertForTesting) {
+  HighContrastSettings settings;
+  settings.mode = HighContrastMode::kSimpleInvertForTesting;
+  settings.grayscale = false;
+  settings.contrast = 0;
+  context_->SetHighContrast(settings);
+
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xff00ffff, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xff7f7f7f, *bitmap_.getAddr32(3, 0));
+}
+
+// Invert brightness (with gamma correction).
+TEST_F(GraphicsContextHighConstrastTest, InvertBrightness) {
+  HighContrastSettings settings;
+  settings.mode = HighContrastMode::kInvertBrightness;
+  settings.grayscale = false;
+  settings.contrast = 0;
+  context_->SetHighContrast(settings);
+
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xff00ffff, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xffdddddd, *bitmap_.getAddr32(3, 0));
+}
+
+// Invert lightness (in HSL space).
+TEST_F(GraphicsContextHighConstrastTest, InvertLightness) {
+  HighContrastSettings settings;
+  settings.mode = HighContrastMode::kInvertLightness;
+  settings.grayscale = false;
+  settings.contrast = 0;
+  context_->SetHighContrast(settings);
+
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xffff0000, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xffdddddd, *bitmap_.getAddr32(3, 0));
+}
+
+// Invert lightness plus grayscale.
+TEST_F(GraphicsContextHighConstrastTest, InvertLightnessPlusGrayscale) {
+  HighContrastSettings settings;
+  settings.mode = HighContrastMode::kInvertLightness;
+  settings.grayscale = true;
+  settings.contrast = 0;
+  context_->SetHighContrast(settings);
+
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xffe2e2e2, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xffdddddd, *bitmap_.getAddr32(3, 0));
+}
+
+TEST_F(GraphicsContextHighConstrastTest, InvertLightnessPlusContrast) {
+  HighContrastSettings settings;
+  settings.mode = HighContrastMode::kInvertLightness;
+  settings.grayscale = false;
+  settings.contrast = 0.2;
+  context_->SetHighContrast(settings);
+
+  DrawColorsToContext();
+
+  EXPECT_EQ(0xffffffff, *bitmap_.getAddr32(0, 0));
+  EXPECT_EQ(0xff000000, *bitmap_.getAddr32(1, 0));
+  EXPECT_EQ(0xffff0000, *bitmap_.getAddr32(2, 0));
+  EXPECT_EQ(0xffeeeeee, *bitmap_.getAddr32(3, 0));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/HighContrastSettings.h b/third_party/WebKit/Source/platform/graphics/HighContrastSettings.h
new file mode 100644
index 0000000..0d5ad2f
--- /dev/null
+++ b/third_party/WebKit/Source/platform/graphics/HighContrastSettings.h
@@ -0,0 +1,27 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HighContrastSettings_h
+#define HighContrastSettings_h
+
+namespace blink {
+
+enum class HighContrastMode {
+  // Default, drawing is unfiltered.
+  kOff,
+  // For testing only, does a simple 8-bit invert of every RGB pixel component.
+  kSimpleInvertForTesting,
+  kInvertBrightness,
+  kInvertLightness,
+};
+
+struct HighContrastSettings {
+  HighContrastMode mode = HighContrastMode::kOff;
+  bool grayscale = false;
+  float contrast = 0.0;  // Valid range from -1.0 to 1.0
+};
+
+}  // namespace blink
+
+#endif  // HighContrastSettings_h
diff --git a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
index 56d0a46..d0fbfed 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
+++ b/third_party/WebKit/Source/platform/graphics/paint/DisplayItem.h
@@ -6,6 +6,7 @@
 #define DisplayItem_h
 
 #include "platform/PlatformExport.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/graphics/ContiguousContainer.h"
 #include "platform/graphics/paint/DisplayItemClient.h"
 #include "platform/wtf/Allocator.h"
@@ -403,7 +404,9 @@
   PairedBeginDisplayItem(const DisplayItemClient& client,
                          Type type,
                          size_t derived_size)
-      : DisplayItem(client, type, derived_size) {}
+      : DisplayItem(client, type, derived_size) {
+    DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+  }
 
  private:
   bool IsBegin() const final { return true; }
@@ -414,7 +417,9 @@
   PairedEndDisplayItem(const DisplayItemClient& client,
                        Type type,
                        size_t derived_size)
-      : DisplayItem(client, type, derived_size) {}
+      : DisplayItem(client, type, derived_size) {
+    DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+  }
 
 #if DCHECK_IS_ON()
   bool IsEndAndPairedWith(DisplayItem::Type other_type) const override = 0;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintRecordBuilder.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintRecordBuilder.cpp
index 27bbcc83..0022d60 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintRecordBuilder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintRecordBuilder.cpp
@@ -37,8 +37,13 @@
   paint_controller_->SetUsage(PaintController::kForPaintRecordBuilder);
 #endif
 
+  const HighContrastSettings* high_contrast_settings =
+      containing_context ? &containing_context->high_contrast_settings()
+                         : nullptr;
   context_ = WTF::WrapUnique(
       new GraphicsContext(*paint_controller_, disabled_mode, meta_data));
+  if (high_contrast_settings)
+    context_->SetHighContrast(*high_contrast_settings);
 
   if (containing_context) {
     context_->SetDeviceScaleFactor(containing_context->DeviceScaleFactor());
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
index 0aaf2954..285f904 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -937,6 +937,18 @@
     widget->GetLayerTreeView()->SetHaveScrollEventHandlers(has_event_handlers);
 }
 
+void ChromeClientImpl::SetNeedsLowLatencyInput(LocalFrame* frame,
+                                               bool needs_low_latency) {
+  DCHECK(frame);
+  WebLocalFrameImpl* web_frame = WebLocalFrameImpl::FromFrame(frame);
+  WebFrameWidgetBase* widget = web_frame->LocalRoot()->FrameWidget();
+  if (!widget)
+    return;
+
+  if (WebWidgetClient* client = widget->Client())
+    client->SetNeedsLowLatencyInput(needs_low_latency);
+}
+
 void ChromeClientImpl::SetTouchAction(LocalFrame* frame,
                                       TouchAction touch_action) {
   DCHECK(frame);
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.h b/third_party/WebKit/Source/web/ChromeClientImpl.h
index f00b2d7..b6f678c 100644
--- a/third_party/WebKit/Source/web/ChromeClientImpl.h
+++ b/third_party/WebKit/Source/web/ChromeClientImpl.h
@@ -144,6 +144,7 @@
   // Informs client about the existence of handlers for scroll events so
   // appropriate scroll optimizations can be chosen.
   void SetHasScrollEventHandlers(LocalFrame*, bool has_event_handlers) override;
+  void SetNeedsLowLatencyInput(LocalFrame*, bool needs_low_latency) override;
   void SetTouchAction(LocalFrame*, TouchAction) override;
   const WebInputEvent* GetCurrentInputEvent() const override;
 
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
index b93512a..2c086b2 100644
--- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -638,7 +638,7 @@
       web_view->MainFrame()->GetDocument().GetElementById(
           WebString::FromUTF8("scrolled-plugin"));
   plugin_container_one_element.PluginContainer()->RequestTouchEventType(
-      WebPluginContainer::kTouchEventRequestTypeRaw);
+      WebPluginContainer::kTouchEventRequestTypeRawLowLatency);
   WebPlugin* plugin = static_cast<WebPluginContainerBase*>(
                           plugin_container_one_element.PluginContainer())
                           ->Plugin();
diff --git a/third_party/WebKit/public/platform/PRESUBMIT.py b/third_party/WebKit/public/platform/PRESUBMIT.py
index 47110974..f3743b6 100644
--- a/third_party/WebKit/public/platform/PRESUBMIT.py
+++ b/third_party/WebKit/public/platform/PRESUBMIT.py
@@ -23,13 +23,13 @@
 
     source_path = ''
     for f in input_api.AffectedFiles():
-        if f.LocalPath().endswith('UseCounterFeature.def'):
+        if f.LocalPath().endswith('WebFeature.h'):
             source_path = f.LocalPath()
             break
     else:
         return []
 
-    start_marker = '^'
+    start_marker = '^enum class WebFeature : uint32_t {'
     end_marker = '^kNumberOfFeatures'
     presubmit_error = update_histogram_enum.CheckPresubmitErrors(
         histogram_enum_name='FeatureObserver',
diff --git a/third_party/WebKit/public/platform/UseCounterFeature.def b/third_party/WebKit/public/platform/UseCounterFeature.def
deleted file mode 100644
index ba1c7f6..0000000
--- a/third_party/WebKit/public/platform/UseCounterFeature.def
+++ /dev/null
@@ -1,1560 +0,0 @@
-// ============ Definition for WebFeature used for UseCounter ===============
-// A WebFeature conceptually represents some particular web-exposed API
-// or code path which can be used/triggered by a web page.
-// TODO(rbyers): Add CSS and animated CSS feature types by making this a
-// more sophisticated class.
-//
-// Do not change assigned numbers of existing items: add new features
-// to the end of the list.
-kOBSOLETE_PageDestruction = 0,
-kWorkerStart = 4,
-kSharedWorkerStart = 5,
-kUnprefixedIndexedDB = 9,
-kOpenWebDatabase = 10,
-kUnprefixedRequestAnimationFrame = 13,
-kPrefixedRequestAnimationFrame = 14,
-kContentSecurityPolicy = 15,
-kContentSecurityPolicyReportOnly = 16,
-kPrefixedTransitionEndEvent = 18,
-kUnprefixedTransitionEndEvent = 19,
-kPrefixedAndUnprefixedTransitionEndEvent = 20,
-kAutoFocusAttribute = 21,
-kDataListElement = 23,
-kFormAttribute = 24,
-kIncrementalAttribute = 25,
-kInputTypeColor = 26,
-kInputTypeDate = 27,
-kInputTypeDateTimeFallback = 29,
-kInputTypeDateTimeLocal = 30,
-kInputTypeEmail = 31,
-kInputTypeMonth = 32,
-kInputTypeNumber = 33,
-kInputTypeRange = 34,
-kInputTypeSearch = 35,
-kInputTypeTel = 36,
-kInputTypeTime = 37,
-kInputTypeURL = 38,
-kInputTypeWeek = 39,
-kInputTypeWeekFallback = 40,
-kListAttribute = 41,
-kMaxAttribute = 42,
-kMinAttribute = 43,
-kPatternAttribute = 44,
-kPlaceholderAttribute = 45,
-kPrefixedDirectoryAttribute = 47,
-kRequiredAttribute = 49,
-kStepAttribute = 51,
-kPageVisits = 52,
-kHTMLMarqueeElement = 53,
-kReflection = 55,
-kPrefixedStorageInfo = 57,
-kDeprecatedFlexboxWebContent = 61,
-kDeprecatedFlexboxChrome = 62,
-kDeprecatedFlexboxChromeExtension = 63,
-kUnprefixedPerformanceTimeline = 65,
-kUnprefixedUserTiming = 67,
-kWindowEvent = 69,
-kContentSecurityPolicyWithBaseElement = 70,
-kDocumentClear = 74,
-kXMLDocument = 77,
-kXSLProcessingInstruction = 78,
-kXSLTProcessor = 79,
-kSVGSwitchElement = 80,
-kDocumentAll = 83,
-kFormElement = 84,
-kDemotedFormElement = 85,
-kSVGAnimationElement = 90,
-kLineClamp = 96,
-kSubFrameBeforeUnloadRegistered = 97,
-kSubFrameBeforeUnloadFired = 98,
-kConsoleMarkTimeline = 102,
-kDocumentCreateAttribute = 111,
-kDocumentCreateAttributeNS = 112,
-kDocumentXMLEncoding = 115,    // Removed from DOM4.
-kDocumentXMLStandalone = 116,  // Removed from DOM4.
-kDocumentXMLVersion = 117,     // Removed from DOM4.
-kNavigatorProductSub = 123,
-kNavigatorVendor = 124,
-kNavigatorVendorSub = 125,
-kPrefixedAnimationEndEvent = 128,
-kUnprefixedAnimationEndEvent = 129,
-kPrefixedAndUnprefixedAnimationEndEvent = 130,
-kPrefixedAnimationStartEvent = 131,
-kUnprefixedAnimationStartEvent = 132,
-kPrefixedAndUnprefixedAnimationStartEvent = 133,
-kPrefixedAnimationIterationEvent = 134,
-kUnprefixedAnimationIterationEvent = 135,
-kPrefixedAndUnprefixedAnimationIterationEvent = 136,
-kEventReturnValue = 137,  // Legacy IE extension.
-kSVGSVGElement = 138,
-kDOMSubtreeModifiedEvent = 143,
-kDOMNodeInsertedEvent = 144,
-kDOMNodeRemovedEvent = 145,
-kDOMNodeRemovedFromDocumentEvent = 146,
-kDOMNodeInsertedIntoDocumentEvent = 147,
-kDOMCharacterDataModifiedEvent = 148,
-kDocumentAllLegacyCall = 150,
-kGetMatchedCSSRules = 155,
-kPrefixedAudioDecodedByteCount = 164,
-kPrefixedVideoDecodedByteCount = 165,
-kPrefixedVideoSupportsFullscreen = 166,
-kPrefixedVideoDisplayingFullscreen = 167,
-kPrefixedVideoEnterFullscreen = 168,
-kPrefixedVideoExitFullscreen = 169,
-kPrefixedVideoEnterFullScreen = 170,
-kPrefixedVideoExitFullScreen = 171,
-kPrefixedVideoDecodedFrameCount = 172,
-kPrefixedVideoDroppedFrameCount = 173,
-kPrefixedElementRequestFullscreen = 176,
-kPrefixedElementRequestFullScreen = 177,
-kBarPropLocationbar = 178,
-kBarPropMenubar = 179,
-kBarPropPersonalbar = 180,
-kBarPropScrollbars = 181,
-kBarPropStatusbar = 182,
-kBarPropToolbar = 183,
-kInputTypeEmailMultiple = 184,
-kInputTypeEmailMaxLength = 185,
-kInputTypeEmailMultipleMaxLength = 186,
-kInputTypeText = 190,
-kInputTypeTextMaxLength = 191,
-kInputTypePassword = 192,
-kInputTypePasswordMaxLength = 193,
-kPrefixedPageVisibility = 196,
-kDocumentBeforeUnloadRegistered = 200,
-kDocumentBeforeUnloadFired = 201,
-kDocumentUnloadRegistered = 202,
-kDocumentUnloadFired = 203,
-kSVGLocatableNearestViewportElement = 204,
-kSVGLocatableFarthestViewportElement = 205,
-kSVGPointMatrixTransform = 209,
-kDOMFocusInOutEvent = 211,
-kFileGetLastModifiedDate = 212,
-kHTMLElementInnerText = 213,
-kHTMLElementOuterText = 214,
-kReplaceDocumentViaJavaScriptURL = 215,
-kElementPrefixedMatchesSelector = 217,
-kCSSStyleSheetRules = 219,
-kCSSStyleSheetAddRule = 220,
-kCSSStyleSheetRemoveRule = 221,
-// The above items are available in M33 branch.
-
-kInitMessageEvent = 222,
-kPrefixedDevicePixelRatioMediaFeature = 233,
-kPrefixedMaxDevicePixelRatioMediaFeature = 234,
-kPrefixedMinDevicePixelRatioMediaFeature = 235,
-kPrefixedTransform3dMediaFeature = 237,
-kPrefixedStorageQuota = 240,
-kResetReferrerPolicy = 243,
-// Case-insensitivity dropped from specification.
-kCaseInsensitiveAttrSelectorMatch = 244,
-kFormNameAccessForImageElement = 246,
-kFormNameAccessForPastNamesMap = 247,
-kFormAssociationByParser = 248,
-kSVGSVGElementInDocument = 250,
-kSVGDocumentRootElement = 251,
-kWorkerSubjectToCSP = 257,
-kWorkerAllowedByChildBlockedByScript = 258,
-kDeprecatedWebKitGradient = 260,
-kDeprecatedWebKitLinearGradient = 261,
-kDeprecatedWebKitRepeatingLinearGradient = 262,
-kDeprecatedWebKitRadialGradient = 263,
-kDeprecatedWebKitRepeatingRadialGradient = 264,
-// The above items are available in M34 branch.
-
-kTextAutosizing = 274,
-kHTMLAnchorElementPingAttribute = 276,
-kSVGClassName = 279,
-kHTMLMediaElementSeekToFragmentStart = 281,
-kHTMLMediaElementPauseAtFragmentEnd = 282,
-kPrefixedWindowURL = 283,
-kWindowOrientation = 285,
-kDocumentCaptureEvents = 287,
-kDocumentReleaseEvents = 288,
-kWindowCaptureEvents = 289,
-kWindowReleaseEvents = 290,
-kDocumentXPathCreateExpression = 295,
-kDocumentXPathCreateNSResolver = 296,
-kDocumentXPathEvaluate = 297,
-kAnimationConstructorKeyframeListEffectObjectTiming = 300,
-kAnimationConstructorKeyframeListEffectNoTiming = 302,
-kPrefixedCancelAnimationFrame = 304,
-kNamedNodeMapGetNamedItem = 306,
-kNamedNodeMapSetNamedItem = 307,
-kNamedNodeMapRemoveNamedItem = 308,
-kNamedNodeMapItem = 309,
-kNamedNodeMapGetNamedItemNS = 310,
-kNamedNodeMapSetNamedItemNS = 311,
-kNamedNodeMapRemoveNamedItemNS = 312,
-kPrefixedDocumentIsFullscreen = 318,
-kPrefixedDocumentCurrentFullScreenElement = 320,
-kPrefixedDocumentCancelFullScreen = 321,
-kPrefixedDocumentFullscreenEnabled = 322,
-kPrefixedDocumentFullscreenElement = 323,
-kPrefixedDocumentExitFullscreen = 324,
-// The above items are available in M35 branch.
-
-kSVGForeignObjectElement = 325,
-kSelectionSetPosition = 327,
-kAnimationFinishEvent = 328,
-kSVGSVGElementInXMLDocument = 329,
-kEventSrcElement = 343,
-kEventCancelBubble = 344,
-kEventPath = 345,
-kNodeIteratorDetach = 347,
-kEventGetReturnValueTrue = 350,
-kEventGetReturnValueFalse = 351,
-kEventSetReturnValueTrue = 352,
-kEventSetReturnValueFalse = 353,
-kWindowOffscreenBuffering = 356,
-kWindowDefaultStatus = 357,
-kWindowDefaultstatus = 358,
-kPrefixedTransitionEventConstructor = 361,
-kPrefixedMutationObserverConstructor = 362,
-kNotificationPermission = 371,
-kRangeDetach = 372,
-kPrefixedFileRelativePath = 386,
-kDocumentCaretRangeFromPoint = 387,
-kElementScrollIntoViewIfNeeded = 389,
-kRangeExpand = 393,
-kHTMLImageElementX = 396,
-kHTMLImageElementY = 397,
-kSelectionBaseNode = 400,
-kSelectionBaseOffset = 401,
-kSelectionExtentNode = 402,
-kSelectionExtentOffset = 403,
-kSelectionType = 404,
-kSelectionModify = 405,
-kSelectionSetBaseAndExtent = 406,
-kSelectionEmpty = 407,
-kVTTCue = 409,
-kVTTCueRender = 410,
-kVTTCueRenderVertical = 411,
-kVTTCueRenderSnapToLinesFalse = 412,
-kVTTCueRenderLineNotAuto = 413,
-kVTTCueRenderPositionNot50 = 414,
-kVTTCueRenderSizeNot100 = 415,
-kVTTCueRenderAlignNotCenter = 416,
-// The above items are available in M36 branch.
-
-kElementRequestPointerLock = 417,
-kVTTCueRenderRtl = 418,
-kPostMessageFromSecureToInsecure = 419,
-kPostMessageFromInsecureToSecure = 420,
-kDocumentExitPointerLock = 421,
-kDocumentPointerLockElement = 422,
-kPrefixedCursorZoomIn = 424,
-kPrefixedCursorZoomOut = 425,
-kTextEncoderConstructor = 429,
-kTextEncoderEncode = 430,
-kTextDecoderConstructor = 431,
-kTextDecoderDecode = 432,
-kFocusInOutEvent = 433,
-kMouseEventMovementX = 434,
-kMouseEventMovementY = 435,
-kDocumentFonts = 440,
-kMixedContentFormsSubmitted = 441,
-kFormsSubmitted = 442,
-kHTMLImports = 455,
-kElementCreateShadowRoot = 456,
-kDocumentRegisterElement = 457,
-kEditingAppleInterchangeNewline = 458,
-kEditingAppleConvertedSpace = 459,
-kEditingApplePasteAsQuotation = 460,
-kEditingAppleStyleSpanClass = 461,
-kHTMLImportsAsyncAttribute = 463,
-kXMLHttpRequestSynchronous = 465,
-kCSSSelectorPseudoUnresolved = 466,
-kCSSSelectorPseudoShadow = 467,
-kCSSSelectorPseudoContent = 468,
-kCSSSelectorPseudoHost = 469,
-kCSSSelectorPseudoHostContext = 470,
-kCSSDeepCombinator = 471,
-// The above items are available in M37 branch.
-
-kUseAsm = 473,
-kDOMWindowOpen = 475,
-kDOMWindowOpenFeatures = 476,
-kAspectRatioFlexItem = 479,
-kDetailsElement = 480,
-kDialogElement = 481,
-kMapElement = 482,
-kMeterElement = 483,
-kProgressElement = 484,
-kWheelEventWheelDeltaX = 491,
-kWheelEventWheelDeltaY = 492,
-kWheelEventWheelDelta = 493,
-kSendBeacon = 494,
-kSendBeaconQuotaExceeded = 495,
-kSVGSMILElementInDocument = 501,
-kMouseEventOffsetX = 502,
-kMouseEventOffsetY = 503,
-kMouseEventX = 504,
-kMouseEventY = 505,
-kMouseEventFromElement = 506,
-kMouseEventToElement = 507,
-kRequestFileSystem = 508,
-kRequestFileSystemWorker = 509,
-kRequestFileSystemSyncWorker = 510,
-kSVGStyleElementTitle = 519,
-kPictureSourceSrc = 520,
-// The above items are available in M38 branch.
-
-kPicture = 521,
-kSizes = 522,
-kSrcsetXDescriptor = 523,
-kSrcsetWDescriptor = 524,
-kSelectionContainsNode = 525,
-kXMLExternalResourceLoad = 529,
-kMixedContentPrivateHostnameInPublicHostname = 530,
-kLegacyProtocolEmbeddedAsSubresource = 531,
-kRequestedSubresourceWithEmbeddedCredentials = 532,
-kNotificationCreated = 533,
-kNotificationClosed = 534,
-kNotificationPermissionRequested = 535,
-kConsoleTimeline = 538,
-kConsoleTimelineEnd = 539,
-kSRIElementWithMatchingIntegrityAttribute = 540,
-kSRIElementWithNonMatchingIntegrityAttribute = 541,
-kSRIElementWithUnparsableIntegrityAttribute = 542,
-kV8Animation_StartTime_AttributeGetter = 545,
-kV8Animation_StartTime_AttributeSetter = 546,
-kV8Animation_CurrentTime_AttributeGetter = 547,
-kV8Animation_CurrentTime_AttributeSetter = 548,
-kV8Animation_PlaybackRate_AttributeGetter = 549,
-kV8Animation_PlaybackRate_AttributeSetter = 550,
-kV8Animation_PlayState_AttributeGetter = 551,
-kV8Animation_Finish_Method = 552,
-kV8Animation_Play_Method = 553,
-kV8Animation_Pause_Method = 554,
-kV8Animation_Reverse_Method = 555,
-// The above items are available in M39 branch.
-
-kBreakIterator = 556,
-kScreenOrientationAngle = 557,
-kScreenOrientationType = 558,
-kScreenOrientationLock = 559,
-kScreenOrientationUnlock = 560,
-kGeolocationSecureOrigin = 561,
-kGeolocationInsecureOrigin = 562,
-kNotificationSecureOrigin = 563,
-kNotificationInsecureOrigin = 564,
-kNotificationShowEvent = 565,
-kSVGTransformListConsolidate = 569,
-kSVGAnimatedTransformListBaseVal = 570,
-kQuotedAnimationName = 571,
-kQuotedKeyframesRule = 572,
-kSrcsetDroppedCandidate = 573,
-kWindowPostMessage = 574,
-kRenderRuby = 576,
-kScriptElementWithInvalidTypeHasSrc = 578,
-kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload = 581,
-kCSSSelectorPseudoScrollbar = 582,
-kCSSSelectorPseudoScrollbarButton = 583,
-kCSSSelectorPseudoScrollbarThumb = 584,
-kCSSSelectorPseudoScrollbarTrack = 585,
-kCSSSelectorPseudoScrollbarTrackPiece = 586,
-kLangAttribute = 587,
-kLangAttributeOnHTML = 588,
-kLangAttributeOnBody = 589,
-kLangAttributeDoesNotMatchToUILocale = 590,
-kInputTypeSubmit = 591,
-kInputTypeSubmitWithValue = 592,
-// The above items are available in M40 branch.
-
-kSetReferrerPolicy = 593,
-kTextWholeText = 599,
-kNotificationCloseEvent = 603,
-kStyleMedia = 606,
-kStyleMediaType = 607,
-kStyleMediaMatchMedium = 608,
-kMixedContentPresent = 609,
-kMixedContentBlockable = 610,
-kMixedContentAudio = 611,
-kMixedContentDownload = 612,
-kMixedContentFavicon = 613,
-kMixedContentImage = 614,
-kMixedContentInternal = 615,
-kMixedContentPlugin = 616,
-kMixedContentPrefetch = 617,
-kMixedContentVideo = 618,
-kCSSSelectorPseudoFullScreenAncestor = 628,
-kCSSSelectorPseudoFullScreen = 629,
-kWebKitCSSMatrix = 630,
-kAudioContextCreateAnalyser = 631,
-kAudioContextCreateBiquadFilter = 632,
-kAudioContextCreateBufferSource = 633,
-kAudioContextCreateChannelMerger = 634,
-kAudioContextCreateChannelSplitter = 635,
-kAudioContextCreateConvolver = 636,
-kAudioContextCreateDelay = 637,
-kAudioContextCreateDynamicsCompressor = 638,
-kAudioContextCreateGain = 639,
-kAudioContextCreateMediaElementSource = 640,
-kAudioContextCreateMediaStreamDestination = 641,
-kAudioContextCreateMediaStreamSource = 642,
-kAudioContextCreateOscillator = 643,
-kAudioContextCreatePeriodicWave = 645,
-kAudioContextCreateScriptProcessor = 646,
-kAudioContextCreateStereoPanner = 647,
-kAudioContextCreateWaveShaper = 648,
-kAudioContextDecodeAudioData = 649,
-kAudioContextResume = 650,
-kAudioContextSuspend = 651,
-kMixedContentInNonHTTPSFrameThatRestrictsMixedContent = 661,
-kMixedContentInSecureFrameThatDoesNotRestrictMixedContent = 662,
-kMixedContentWebSocket = 663,
-kSyntheticKeyframesInCompositedCSSAnimation = 664,
-kMixedContentFormPresent = 665,
-kGetUserMediaInsecureOrigin = 666,
-kGetUserMediaSecureOrigin = 667,
-// The above items are available in M41 branch.
-
-kDeviceMotionInsecureOrigin = 668,
-kDeviceMotionSecureOrigin = 669,
-kDeviceOrientationInsecureOrigin = 670,
-kDeviceOrientationSecureOrigin = 671,
-kSandboxViaIFrame = 672,
-kSandboxViaCSP = 673,
-kBlockedSniffingImageToScript = 674,
-kFetch = 675,
-kFetchBodyStream = 676,
-kXMLHttpRequestAsynchronous = 677,
-kWhiteSpacePreFromXMLSpace = 679,
-kWhiteSpaceNowrapFromXMLSpace = 680,
-kSVGSVGElementForceRedraw = 685,
-kSVGSVGElementSuspendRedraw = 686,
-kSVGSVGElementUnsuspendRedraw = 687,
-kSVGSVGElementUnsuspendRedrawAll = 688,
-kAudioContextClose = 689,
-kCSSZoomNotEqualToOne = 691,
-// The above items are available in M42 branch.
-
-kClientRectListItem = 694,
-kWindowClientInformation = 695,
-kWindowFind = 696,
-kWindowScreenLeft = 697,
-kWindowScreenTop = 698,
-kV8Animation_Cancel_Method = 699,
-kV8Animation_Onfinish_AttributeGetter = 700,
-kV8Animation_Onfinish_AttributeSetter = 701,
-kV8Window_WebKitAnimationEvent_ConstructorGetter = 707,
-kCryptoGetRandomValues = 710,
-kSubtleCryptoEncrypt = 711,
-kSubtleCryptoDecrypt = 712,
-kSubtleCryptoSign = 713,
-kSubtleCryptoVerify = 714,
-kSubtleCryptoDigest = 715,
-kSubtleCryptoGenerateKey = 716,
-kSubtleCryptoImportKey = 717,
-kSubtleCryptoExportKey = 718,
-kSubtleCryptoDeriveBits = 719,
-kSubtleCryptoDeriveKey = 720,
-kSubtleCryptoWrapKey = 721,
-kSubtleCryptoUnwrapKey = 722,
-kCryptoAlgorithmAesCbc = 723,
-kCryptoAlgorithmHmac = 724,
-kCryptoAlgorithmRsaSsaPkcs1v1_5 = 725,
-kCryptoAlgorithmSha1 = 726,
-kCryptoAlgorithmSha256 = 727,
-kCryptoAlgorithmSha384 = 728,
-kCryptoAlgorithmSha512 = 729,
-kCryptoAlgorithmAesGcm = 730,
-kCryptoAlgorithmRsaOaep = 731,
-kCryptoAlgorithmAesCtr = 732,
-kCryptoAlgorithmAesKw = 733,
-kCryptoAlgorithmRsaPss = 734,
-kCryptoAlgorithmEcdsa = 735,
-kCryptoAlgorithmEcdh = 736,
-kCryptoAlgorithmHkdf = 737,
-kCryptoAlgorithmPbkdf2 = 738,
-kDocumentSetDomain = 739,
-kUpgradeInsecureRequestsEnabled = 740,
-kUpgradeInsecureRequestsUpgradedRequest = 741,
-kDocumentDesignMode = 742,
-kGlobalCacheStorage = 743,
-kNetInfo = 744,
-kBackgroundSync = 745,
-kLegacyConst = 748,
-kV8Permissions_Query_Method = 750,
-// The above items are available in M43 branch.
-
-kV8HTMLInputElement_Autocapitalize_AttributeGetter = 754,
-kV8HTMLInputElement_Autocapitalize_AttributeSetter = 755,
-kV8HTMLTextAreaElement_Autocapitalize_AttributeGetter = 756,
-kV8HTMLTextAreaElement_Autocapitalize_AttributeSetter = 757,
-kSVGHrefBaseVal = 758,
-kSVGHrefAnimVal = 759,
-kV8CSSRuleList_Item_Method = 760,
-kV8MediaList_Item_Method = 761,
-kV8StyleSheetList_Item_Method = 762,
-kStyleSheetListAnonymousNamedGetter = 763,
-kAutocapitalizeAttribute = 764,
-kFullscreenSecureOrigin = 765,
-kFullscreenInsecureOrigin = 766,
-kDialogInSandboxedContext = 767,
-kSVGSMILAnimationInImageRegardlessOfCache = 768,
-kPerformanceFrameTiming = 772,
-kV8Element_Animate_Method = 773,
-// The above items are available in M44 branch.
-
-kV8SVGSVGElement_GetElementById_Method = 778,
-kElementCreateShadowRootMultiple = 779,
-kV8MessageChannel_Constructor = 780,
-kV8MessagePort_PostMessage_Method = 781,
-kV8MessagePort_Start_Method = 782,
-kV8MessagePort_Close_Method = 783,
-kMessagePortsTransferred = 784,
-kCSSKeyframesRuleAnonymousIndexedGetter = 785,
-kV8Screen_AvailLeft_AttributeGetter = 786,
-kV8Screen_AvailTop_AttributeGetter = 787,
-kV8SVGFEConvolveMatrixElement_PreserveAlpha_AttributeGetter = 791,
-kV8SVGStyleElement_Disabled_AttributeGetter = 798,
-kV8SVGStyleElement_Disabled_AttributeSetter = 799,
-kInputTypeFileSecureOrigin = 801,
-kInputTypeFileInsecureOrigin = 802,
-kElementAttachShadow = 804,
-kV8SecurityPolicyViolationEvent_DocumentURI_AttributeGetter = 806,
-kV8SecurityPolicyViolationEvent_BlockedURI_AttributeGetter = 807,
-kV8SecurityPolicyViolationEvent_StatusCode_AttributeGetter = 808,
-kHTMLLinkElementDisabled = 809,
-kV8HTMLLinkElement_Disabled_AttributeGetter = 810,
-kV8HTMLLinkElement_Disabled_AttributeSetter = 811,
-kV8HTMLStyleElement_Disabled_AttributeGetter = 812,
-kV8HTMLStyleElement_Disabled_AttributeSetter = 813,
-kV8DOMError_Constructor = 816,
-kV8DOMError_Name_AttributeGetter = 817,
-kV8DOMError_Message_AttributeGetter = 818,
-kTextInputFired = 830,
-kV8TextEvent_Data_AttributeGetter = 831,
-kV8TextEvent_InitTextEvent_Method = 832,
-kClientHintsDPR = 835,
-kClientHintsResourceWidth = 836,
-kClientHintsViewportWidth = 837,
-kSRIElementIntegrityAttributeButIneligible = 838,
-kFormDataAppendNull = 843,
-kNonHTMLElementSetAttributeNodeFromHTMLDocumentNameNotLowercase = 845,
-kNavigatorVibrate = 850,
-kNavigatorVibrateSubFrame = 851,
-kV8XPathEvaluator_Constructor = 853,
-kV8XPathEvaluator_CreateExpression_Method = 854,
-kV8XPathEvaluator_CreateNSResolver_Method = 855,
-kV8XPathEvaluator_Evaluate_Method = 856,
-kRequestMIDIAccess = 857,
-kV8MouseEvent_LayerX_AttributeGetter = 858,
-kV8MouseEvent_LayerY_AttributeGetter = 859,
-kInnerTextWithShadowTree = 860,
-kSelectionToStringWithShadowTree = 861,
-kWindowFindWithShadowTree = 862,
-kV8CompositionEvent_InitCompositionEvent_Method = 863,
-kV8CustomEvent_InitCustomEvent_Method = 864,
-kV8DeviceMotionEvent_InitDeviceMotionEvent_Method = 865,
-kV8DeviceOrientationEvent_InitDeviceOrientationEvent_Method = 866,
-kV8Event_InitEvent_Method = 867,
-kV8KeyboardEvent_InitKeyboardEvent_Method = 868,
-kV8MouseEvent_InitMouseEvent_Method = 869,
-kV8MutationEvent_InitMutationEvent_Method = 870,
-kV8StorageEvent_InitStorageEvent_Method = 871,
-kV8UIEvent_InitUIEvent_Method = 873,
-kV8Document_CreateTouch_Method = 874,
-kRequestFileSystemNonWebbyOrigin = 876,
-kV8MemoryInfo_TotalJSHeapSize_AttributeGetter = 879,
-kV8MemoryInfo_UsedJSHeapSize_AttributeGetter = 880,
-kV8MemoryInfo_JSHeapSizeLimit_AttributeGetter = 881,
-kV8Performance_Timing_AttributeGetter = 882,
-kV8Performance_Navigation_AttributeGetter = 883,
-kV8Performance_Memory_AttributeGetter = 884,
-kV8SharedWorker_WorkerStart_AttributeGetter = 885,
-// The above items are available in M45 branch.
-
-kHTMLMediaElementPreloadNone = 892,
-kHTMLMediaElementPreloadMetadata = 893,
-kHTMLMediaElementPreloadAuto = 894,
-kHTMLMediaElementPreloadDefault = 895,
-kMixedContentBlockableAllowed = 896,
-kPseudoBeforeAfterForInputElement = 897,
-kV8Permissions_Revoke_Method = 898,
-kLinkRelDnsPrefetch = 899,
-kLinkRelPreconnect = 900,
-kLinkRelPreload = 901,
-kLinkHeaderDnsPrefetch = 902,
-kLinkHeaderPreconnect = 903,
-kClientHintsMetaAcceptCH = 904,
-kHTMLElementDeprecatedWidth = 905,
-kClientHintsContentDPR = 906,
-kElementAttachShadowOpen = 907,
-kElementAttachShadowClosed = 908,
-kAudioParamSetValueAtTime = 909,
-kAudioParamLinearRampToValueAtTime = 910,
-kAudioParamExponentialRampToValueAtTime = 911,
-kAudioParamSetTargetAtTime = 912,
-kAudioParamSetValueCurveAtTime = 913,
-kAudioParamCancelScheduledValues = 914,
-kV8Permissions_Request_Method = 915,
-kLinkRelPrefetch = 917,
-kLinkRelPrerender = 918,
-kLinkRelNext = 919,
-kCSSValuePrefixedMinContent = 921,
-kCSSValuePrefixedMaxContent = 922,
-kCSSValuePrefixedFitContent = 923,
-kCSSValuePrefixedFillAvailable = 924,
-kPresentationDefaultRequest = 926,
-kPresentationAvailabilityChangeEventListener = 927,
-kPresentationRequestConstructor = 928,
-kPresentationRequestStart = 929,
-kPresentationRequestReconnect = 930,
-kPresentationRequestGetAvailability = 931,
-kPresentationRequestConnectionAvailableEventListener = 932,
-kPresentationConnectionTerminate = 933,
-kPresentationConnectionSend = 934,
-kPresentationConnectionMessageEventListener = 936,
-kCSSAnimationsStackedNeutralKeyframe = 937,
-kReadingCheckedInClickHandler = 938,
-kFlexboxIntrinsicSizeAlgorithmIsDifferent = 939,
-// The above items are available in M46 branch.
-
-kHTMLImportsHasStyleSheets = 940,
-kNetInfoType = 946,
-kNetInfoDownlinkMax = 947,
-kNetInfoOnChange = 948,
-kNetInfoOnTypeChange = 949,
-kV8Window_Alert_Method = 950,
-kV8Window_Confirm_Method = 951,
-kV8Window_Prompt_Method = 952,
-kV8Window_Print_Method = 953,
-kV8Window_RequestIdleCallback_Method = 954,
-kFlexboxPercentagePaddingVertical = 955,
-kFlexboxPercentageMarginVertical = 956,
-kBackspaceNavigatedBack = 957,
-kBackspaceNavigatedBackAfterFormInteraction = 958,
-kCSPSourceWildcardWouldMatchExactHost = 959,
-kCredentialManagerGet = 960,
-kCredentialManagerGetMediationOptional = 961,
-kCredentialManagerGetMediationSilent = 962,
-kCredentialManagerStore = 963,
-kCredentialManagerRequireUserMediation = 964,
-// The above items are available in M47 branch.
-
-kBlockableMixedContentInSubframeBlocked = 966,
-kAddEventListenerThirdArgumentIsObject = 967,
-kRemoveEventListenerThirdArgumentIsObject = 968,
-kCSSAtRuleCharset = 969,
-kCSSAtRuleFontFace = 970,
-kCSSAtRuleImport = 971,
-kCSSAtRuleKeyframes = 972,
-kCSSAtRuleMedia = 973,
-kCSSAtRuleNamespace = 974,
-kCSSAtRulePage = 975,
-kCSSAtRuleSupports = 976,
-kCSSAtRuleViewport = 977,
-kCSSAtRuleWebkitKeyframes = 978,
-kV8HTMLFieldSetElement_Elements_AttributeGetter = 979,
-kHTMLMediaElementPreloadForcedNone = 980,
-kExternalAddSearchProvider = 981,
-kExternalIsSearchProviderInstalled = 982,
-kV8Permissions_RequestAll_Method = 983,
-kDeviceOrientationAbsoluteInsecureOrigin = 987,
-kDeviceOrientationAbsoluteSecureOrigin = 988,
-kFontFaceConstructor = 989,
-kServiceWorkerControlledPage = 990,
-kMeterElementWithMeterAppearance = 993,
-kMeterElementWithNoneAppearance = 994,
-kSelectionAnchorNode = 997,
-kSelectionAnchorOffset = 998,
-kSelectionFocusNode = 999,
-kSelectionFocusOffset = 1000,
-kSelectionIsCollapsed = 1001,
-kSelectionRangeCount = 1002,
-kSelectionGetRangeAt = 1003,
-kSelectionAddRange = 1004,
-kSelectionRemoveAllRanges = 1005,
-kSelectionCollapse = 1006,
-kSelectionCollapseToStart = 1007,
-kSelectionCollapseToEnd = 1008,
-kSelectionExtend = 1009,
-kSelectionSelectAllChildren = 1010,
-kSelectionDeleteDromDocument = 1011,
-kSelectionDOMString = 1012,
-kInputTypeRangeVerticalAppearance = 1013,
-// The above items are available in M48 branch.
-
-kCSSFilterReference = 1014,
-kCSSFilterGrayscale = 1015,
-kCSSFilterSepia = 1016,
-kCSSFilterSaturate = 1017,
-kCSSFilterHueRotate = 1018,
-kCSSFilterInvert = 1019,
-kCSSFilterOpacity = 1020,
-kCSSFilterBrightness = 1021,
-kCSSFilterContrast = 1022,
-kCSSFilterBlur = 1023,
-kCSSFilterDropShadow = 1024,
-kBackgroundSyncRegister = 1025,
-kExecCommandOnInputOrTextarea = 1027,
-kV8History_ScrollRestoration_AttributeGetter = 1028,
-kV8History_ScrollRestoration_AttributeSetter = 1029,
-kSVG1DOMFilter = 1030,
-kOfflineAudioContextStartRendering = 1031,
-kOfflineAudioContextSuspend = 1032,
-kOfflineAudioContextResume = 1033,
-kSVG1DOMPaintServer = 1035,
-kSVGSVGElementFragmentSVGView = 1036,
-kSVGSVGElementFragmentSVGViewElement = 1037,
-kPresentationConnectionClose = 1038,
-kSVG1DOMShape = 1039,
-kSVG1DOMText = 1040,
-kRTCPeerConnectionConstructorConstraints = 1041,
-kRTCPeerConnectionConstructorCompliant = 1042,
-kRTCPeerConnectionCreateOfferLegacyFailureCallback = 1044,
-kRTCPeerConnectionCreateOfferLegacyConstraints = 1045,
-kRTCPeerConnectionCreateOfferLegacyOfferOptions = 1046,
-kRTCPeerConnectionCreateOfferLegacyCompliant = 1047,
-kRTCPeerConnectionCreateAnswerLegacyFailureCallback = 1049,
-kRTCPeerConnectionCreateAnswerLegacyConstraints = 1050,
-kRTCPeerConnectionCreateAnswerLegacyCompliant = 1051,
-kRTCPeerConnectionSetLocalDescriptionLegacyNoSuccessCallback = 1052,
-kRTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback = 1053,
-kRTCPeerConnectionSetLocalDescriptionLegacyCompliant = 1054,
-kRTCPeerConnectionSetRemoteDescriptionLegacyNoSuccessCallback = 1055,
-kRTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback = 1056,
-kRTCPeerConnectionSetRemoteDescriptionLegacyCompliant = 1057,
-kRTCPeerConnectionGetStatsLegacyNonCompliant = 1058,
-kNodeFilterIsFunction = 1059,
-kNodeFilterIsObject = 1060,
-kCSSSelectorInternalPseudoListBox = 1062,
-kCSSSelectorInternalMediaControlsOverlayCastButton = 1064,
-kCSSSelectorInternalPseudoSpatialNavigationFocus = 1065,
-kSameOriginTextScript = 1066,
-kSameOriginApplicationScript = 1067,
-kSameOriginOtherScript = 1068,
-kCrossOriginTextScript = 1069,
-kCrossOriginApplicationScript = 1070,
-kCrossOriginOtherScript = 1071,
-kSVG1DOMSVGTests = 1072,
-kDisableRemotePlaybackAttribute = 1074,
-kV8SloppyMode = 1075,
-kV8StrictMode = 1076,
-kV8StrongMode = 1077,
-kAudioNodeConnectToAudioNode = 1078,
-kAudioNodeConnectToAudioParam = 1079,
-kAudioNodeDisconnectFromAudioNode = 1080,
-kAudioNodeDisconnectFromAudioParam = 1081,
-kV8CSSFontFaceRule_Style_AttributeGetter = 1082,
-kSelectionCollapseNull = 1083,
-kSelectionSetBaseAndExtentNull = 1084,
-kV8SVGSVGElement_CreateSVGNumber_Method = 1085,
-kV8SVGSVGElement_CreateSVGLength_Method = 1086,
-kV8SVGSVGElement_CreateSVGAngle_Method = 1087,
-kV8SVGSVGElement_CreateSVGPoint_Method = 1088,
-kV8SVGSVGElement_CreateSVGMatrix_Method = 1089,
-kV8SVGSVGElement_CreateSVGRect_Method = 1090,
-kV8SVGSVGElement_CreateSVGTransform_Method = 1091,
-kV8SVGSVGElement_CreateSVGTransformFromMatrix_Method = 1092,
-kFormNameAccessForNonDescendantImageElement = 1093,
-kV8RegExpPrototypeStickyGetter = 1096,
-kV8RegExpPrototypeToString = 1097,
-kV8InputDeviceCapabilities_FiresTouchEvents_AttributeGetter = 1098,
-kDataElement = 1099,
-kTimeElement = 1100,
-kSVG1DOMUriReference = 1101,
-kSVG1DOMZoomAndPan = 1102,
-kV8SVGGraphicsElement_Transform_AttributeGetter = 1103,
-kMenuItemElement = 1104,
-kMenuItemCloseTag = 1105,
-kSVG1DOMMarkerElement = 1106,
-kSVG1DOMUseElement = 1107,
-kSVG1DOMMaskElement = 1108,
-kV8SVGAElement_Target_AttributeGetter = 1109,
-kV8SVGClipPathElement_ClipPathUnits_AttributeGetter = 1110,
-kSVG1DOMFitToViewBox = 1111,
-kSVG1DOMSVGElement = 1114,
-kSVG1DOMImageElement = 1115,
-kSVG1DOMForeignObjectElement = 1116,
-kAudioContextCreateIIRFilter = 1117,
-// The above items are available in M49 branch
-
-kCSSSelectorPseudoSlotted = 1118,
-kMediaDevicesEnumerateDevices = 1119,
-kNonSecureSharedWorkerAccessedFromSecureContext = 1120,
-kSecureSharedWorkerAccessedFromNonSecureContext = 1121,
-kEventComposedPath = 1123,
-kLinkHeaderPreload = 1124,
-kMouseWheelEvent = 1125,
-kWheelEvent = 1126,
-kMouseWheelAndWheelEvent = 1127,
-kBodyScrollsInAdditionToViewport = 1128,
-kDocumentDesignModeEnabeld = 1129,
-kContentEditableTrue = 1130,
-kContentEditableTrueOnHTML = 1131,
-kContentEditablePlainTextOnly = 1132,
-kV8RegExpPrototypeUnicodeGetter = 1133,
-kV8IntlV8Parse = 1134,
-kV8IntlPattern = 1135,
-kV8IntlResolved = 1136,
-kV8PromiseChain = 1137,
-kV8PromiseAccept = 1138,
-kV8PromiseDefer = 1139,
-kEventComposed = 1140,
-kGeolocationInsecureOriginIframe = 1141,
-kGeolocationSecureOriginIframe = 1142,
-kRequestMIDIAccessIframe = 1143,
-kGetUserMediaInsecureOriginIframe = 1144,
-kGetUserMediaSecureOriginIframe = 1145,
-kElementRequestPointerLockIframe = 1146,
-kNotificationAPIInsecureOriginIframe = 1147,
-kNotificationAPISecureOriginIframe = 1148,
-kWebSocket = 1149,
-kMediaStreamConstraintsNameValue = 1150,
-kMediaStreamConstraintsFromDictionary = 1151,
-kMediaStreamConstraintsConformant = 1152,
-kCSSSelectorIndirectAdjacent = 1153,
-kCreateImageBitmap = 1156,
-kPresentationConnectionConnectEventListener = 1157,
-kPresentationConnectionCloseEventListener = 1158,
-kPresentationConnectionTerminateEventListener = 1159,
-kDocumentCreateEventAnimationEvent = 1162,
-kDocumentCreateEventBeforeUnloadEvent = 1166,
-kDocumentCreateEventCompositionEvent = 1168,
-kDocumentCreateEventDragEvent = 1169,
-kDocumentCreateEventErrorEvent = 1170,
-kDocumentCreateEventFocusEvent = 1171,
-kDocumentCreateEventHashChangeEvent = 1172,
-kDocumentCreateEventMutationEvent = 1173,
-kDocumentCreateEventPageTransitionEvent = 1174,
-kDocumentCreateEventPopStateEvent = 1176,
-kDocumentCreateEventTextEvent = 1182,
-kDocumentCreateEventTransitionEvent = 1183,
-kDocumentCreateEventWheelEvent = 1184,
-kDocumentCreateEventTrackEvent = 1186,
-kDocumentCreateEventMutationEvents = 1188,
-kDocumentCreateEventSVGEvents = 1190,
-kDocumentCreateEventDeviceMotionEvent = 1195,
-kDocumentCreateEventDeviceOrientationEvent = 1196,
-kDocumentCreateEventIDBVersionChangeEvent = 1201,
-kDocumentCreateEventStorageEvent = 1221,
-kDocumentCreateEventWebGLContextEvent = 1224,
-kDocumentCreateEventCloseEvent = 1227,
-kDocumentCreateEventKeyboardEvents = 1228,
-kHTMLMediaElement = 1229,
-kHTMLMediaElementInDocument = 1230,
-kHTMLMediaElementControlsAttribute = 1231,
-kV8Animation_Oncancel_AttributeGetter = 1233,
-kV8Animation_Oncancel_AttributeSetter = 1234,
-kV8HTMLCommentInExternalScript = 1235,
-kV8HTMLComment = 1236,
-kV8SloppyModeBlockScopedFunctionRedefinition = 1237,
-kV8ForInInitializer = 1238,
-kV8Animation_Id_AttributeGetter = 1239,
-kV8Animation_Id_AttributeSetter = 1240,
-kApplicationCacheManifestSelectInsecureOrigin = 1245,
-kApplicationCacheManifestSelectSecureOrigin = 1246,
-kApplicationCacheAPIInsecureOrigin = 1247,
-kApplicationCacheAPISecureOrigin = 1248,
-// The above items are available in M50 branch
-
-kCSSAtRuleApply = 1249,
-kCSSSelectorPseudoAny = 1250,
-kDocumentAllItemNoArguments = 1252,
-kDocumentAllItemNamed = 1253,
-kDocumentAllItemIndexed = 1254,
-kDocumentAllItemIndexedWithNonNumber = 1255,
-kDocumentAllLegacyCallNoArguments = 1256,
-kDocumentAllLegacyCallNamed = 1257,
-kDocumentAllLegacyCallIndexed = 1258,
-kDocumentAllLegacyCallIndexedWithNonNumber = 1259,
-kDocumentAllLegacyCallTwoArguments = 1260,
-kHTMLLabelElementControlForNonFormAssociatedElement = 1263,
-kHTMLMediaElementLoadNetworkEmptyNotPaused = 1265,
-kV8Window_WebkitSpeechGrammar_ConstructorGetter = 1267,
-kV8Window_WebkitSpeechGrammarList_ConstructorGetter = 1268,
-kV8Window_WebkitSpeechRecognition_ConstructorGetter = 1269,
-kV8Window_WebkitSpeechRecognitionError_ConstructorGetter = 1270,
-kV8Window_WebkitSpeechRecognitionEvent_ConstructorGetter = 1271,
-kV8Window_SpeechSynthesis_AttributeGetter = 1272,
-kV8IDBFactory_WebkitGetDatabaseNames_Method = 1273,
-kImageDocument = 1274,
-kScriptPassesCSPDynamic = 1275,
-kCSPWithStrictDynamic = 1277,
-kScrollAnchored = 1278,
-kAddEventListenerFourArguments = 1279,
-kRemoveEventListenerFourArguments = 1280,
-kSVGCalcModeDiscrete = 1287,
-kSVGCalcModeLinear = 1288,
-kSVGCalcModePaced = 1289,
-kSVGCalcModeSpline = 1290,
-kFormSubmissionStarted = 1291,
-kFormValidationStarted = 1292,
-kFormValidationAbortedSubmission = 1293,
-kFormValidationShowedMessage = 1294,
-kWebAnimationsEasingAsFunctionLinear = 1295,
-kWebAnimationsEasingAsFunctionOther = 1296,
-// The above items are available in M51 branch
-
-kV8Document_Images_AttributeGetter = 1297,
-kV8Document_Embeds_AttributeGetter = 1298,
-kV8Document_Plugins_AttributeGetter = 1299,
-kV8Document_Links_AttributeGetter = 1300,
-kV8Document_Forms_AttributeGetter = 1301,
-kV8Document_Scripts_AttributeGetter = 1302,
-kV8Document_Anchors_AttributeGetter = 1303,
-kV8Document_Applets_AttributeGetter = 1304,
-kXMLHttpRequestCrossOriginWithCredentials = 1305,
-kMediaStreamTrackRemote = 1306,
-kV8Node_IsConnected_AttributeGetter = 1307,
-kShadowRootDelegatesFocus = 1308,
-kMixedShadowRootV0AndV1 = 1309,
-kImageDocumentInFrame = 1310,
-kMediaDocument = 1311,
-kMediaDocumentInFrame = 1312,
-kPluginDocument = 1313,
-kPluginDocumentInFrame = 1314,
-kSinkDocument = 1315,
-kSinkDocumentInFrame = 1316,
-kTextDocument = 1317,
-kTextDocumentInFrame = 1318,
-kViewSourceDocument = 1319,
-kFileAPINativeLineEndings = 1320,
-kPointerEventAttributeCount = 1321,
-kCompositedReplication = 1322,
-kV8DataTransferItem_WebkitGetAsEntry_Method = 1325,
-kV8HTMLInputElement_WebkitEntries_AttributeGetter = 1326,
-kEntry_Filesystem_AttributeGetter_IsolatedFileSystem = 1327,
-kEntry_GetMetadata_Method_IsolatedFileSystem = 1328,
-kEntry_MoveTo_Method_IsolatedFileSystem = 1329,
-kEntry_CopyTo_Method_IsolatedFileSystem = 1330,
-kEntry_Remove_Method_IsolatedFileSystem = 1331,
-kEntry_GetParent_Method_IsolatedFileSystem = 1332,
-kEntry_ToURL_Method_IsolatedFileSystem = 1333,
-kDuring_Microtask_Alert = 1334,
-kDuring_Microtask_Confirm = 1335,
-kDuring_Microtask_Print = 1336,
-kDuring_Microtask_Prompt = 1337,
-kDuring_Microtask_SyncXHR = 1338,
-kCredentialManagerGetReturnedCredential = 1342,
-kGeolocationInsecureOriginDeprecatedNotRemoved = 1343,
-kGeolocationInsecureOriginIframeDeprecatedNotRemoved = 1344,
-kProgressElementWithNoneAppearance = 1345,
-kProgressElementWithProgressBarAppearance = 1346,
-kPointerEventAddListenerCount = 1347,
-kCSSValueAppearanceNone = 1351,
-kCSSValueAppearanceNotNone = 1352,
-kCSSValueAppearanceOthers = 1353,
-kCSSValueAppearanceButton = 1354,
-kCSSValueAppearanceCaret = 1355,
-kCSSValueAppearanceCheckbox = 1356,
-kCSSValueAppearanceMenulist = 1357,
-kCSSValueAppearanceMenulistButton = 1358,
-kCSSValueAppearanceListbox = 1359,
-kCSSValueAppearanceRadio = 1360,
-kCSSValueAppearanceSearchField = 1361,
-kCSSValueAppearanceTextField = 1362,
-kAudioContextCreatePannerAutomated = 1363,
-kPannerNodeSetPosition = 1364,
-kPannerNodeSetOrientation = 1365,
-kAudioListenerSetPosition = 1366,
-kAudioListenerSetOrientation = 1367,
-kIntersectionObserver_Constructor = 1368,
-kDurableStoragePersist = 1369,
-kDurableStoragePersisted = 1370,
-kDurableStorageEstimate = 1371,
-kCSSDeepCombinatorAndShadow = 1375,
-kOpacityWithPreserve3DQuirk = 1376,
-kCSSSelectorPseudoReadOnly = 1377,
-kCSSSelectorPseudoReadWrite = 1378,
-// The above items are available in M52 branch
-
-kCSSSelectorPseudoDefined = 1383,
-kRTCPeerConnectionAddIceCandidatePromise = 1384,
-kRTCPeerConnectionAddIceCandidateLegacy = 1385,
-kRTCIceCandidateDefaultSdpMLineIndex = 1386,
-kMediaStreamConstraintsOldAndNew = 1389,
-kV8ArrayProtectorDirtied = 1390,
-kV8ArraySpeciesModified = 1391,
-kV8ArrayPrototypeConstructorModified = 1392,
-kV8ArrayInstanceProtoModified = 1393,
-kV8ArrayInstanceConstructorModified = 1394,
-kV8LegacyFunctionDeclaration = 1395,
-kV8RegExpPrototypeSourceGetter = 1396,
-kV8RegExpPrototypeOldFlagGetter = 1397,
-kV8DecimalWithLeadingZeroInStrictMode = 1398,
-kGetUserMediaPrefixed = 1400,
-kGetUserMediaLegacy = 1401,
-kGetUserMediaPromise = 1402,
-kCSSFilterFunctionNoArguments = 1403,
-kV8LegacyDateParser = 1404,
-kOpenSearchInsecureOriginInsecureTarget = 1405,
-kOpenSearchInsecureOriginSecureTarget = 1406,
-kOpenSearchSecureOriginInsecureTarget = 1407,
-kOpenSearchSecureOriginSecureTarget = 1408,
-kRegisterProtocolHandlerSecureOrigin = 1409,
-kRegisterProtocolHandlerInsecureOrigin = 1410,
-kCrossOriginWindowAlert = 1411,
-kCrossOriginWindowConfirm = 1412,
-kCrossOriginWindowPrompt = 1413,
-kCrossOriginWindowPrint = 1414,
-kMediaStreamOnActive = 1415,
-kMediaStreamOnInactive = 1416,
-kAddEventListenerPassiveTrue = 1417,
-kAddEventListenerPassiveFalse = 1418,
-kCSPReferrerDirective = 1419,
-kDocumentOpen = 1420,
-kElementRequestPointerLockInShadow = 1421,
-kShadowRootPointerLockElement = 1422,
-kDocumentPointerLockElementInV0Shadow = 1423,
-kTextAreaMaxLength = 1424,
-kTextAreaMinLength = 1425,
-kTopNavigationFromSubFrame = 1426,
-kPrefixedElementRequestFullscreenInShadow = 1427,
-kMediaSourceAbortRemove = 1428,
-kMediaSourceDurationTruncatingBuffered = 1429,
-kAudioContextCrossOriginIframe = 1430,
-// The above items are available in M53 branch
-
-kPointerEventSetCapture = 1431,
-kPointerEventDispatch = 1432,
-kMIDIMessageEventReceivedTime = 1433,
-kSummaryElementWithDisplayBlockAuthorRule = 1434,
-kV8MediaStream_Active_AttributeGetter = 1435,
-kBeforeInstallPromptEvent = 1436,
-kBeforeInstallPromptEventUserChoice = 1437,
-kBeforeInstallPromptEventPreventDefault = 1438,
-kBeforeInstallPromptEventPrompt = 1439,
-kExecCommandAltersHTMLStructure = 1440,
-kSecureContextCheckPassed = 1441,
-kSecureContextCheckFailed = 1442,
-kSecureContextCheckForSandboxedOriginPassed = 1443,
-kSecureContextCheckForSandboxedOriginFailed = 1444,
-kV8DefineGetterOrSetterWouldThrow = 1445,
-kV8FunctionConstructorReturnedUndefined = 1446,
-kV8BroadcastChannel_Constructor = 1447,
-kV8BroadcastChannel_PostMessage_Method = 1448,
-kV8BroadcastChannel_Close_Method = 1449,
-kTouchStartFired = 1450,
-kMouseDownFired = 1451,
-kPointerDownFired = 1452,
-kPointerDownFiredForTouch = 1453,
-kPointerEventDispatchPointerDown = 1454,
-kSVGSMILBeginOrEndEventValue = 1455,
-kSVGSMILBeginOrEndSyncbaseValue = 1456,
-kSVGSMILElementInsertedAfterLoad = 1457,
-kV8VisualViewport_OffsetLeft_AttributeGetter = 1458,
-kV8VisualViewport_OffsetTop_AttributeGetter = 1459,
-kV8VisualViewport_PageLeft_AttributeGetter = 1460,
-kV8VisualViewport_PageTop_AttributeGetter = 1461,
-kV8VisualViewport_Width_AttributeGetter = 1462,
-kV8VisualViewport_Height_AttributeGetter = 1463,
-kV8VisualViewport_Scale_AttributeGetter = 1464,
-kVisualViewportScrollFired = 1465,
-kVisualViewportResizeFired = 1466,
-kNodeGetRootNode = 1467,
-kSlotChangeEventAddListener = 1468,
-kCSSValueAppearanceButtonRendered = 1469,
-kCSSValueAppearanceButtonForAnchor = 1470,
-kCSSValueAppearanceButtonForButton = 1471,
-kCSSValueAppearanceButtonForOtherButtons = 1472,
-kCSSValueAppearanceTextFieldRendered = 1473,
-kCSSValueAppearanceTextFieldForSearch = 1474,
-kCSSValueAppearanceTextFieldForTextField = 1475,
-kRTCPeerConnectionGetStats = 1476,
-kSVGSMILAnimationAppliedEffect = 1477,
-kPerformanceResourceTimingSizes = 1478,
-kEventSourceDocument = 1479,
-kEventSourceWorker = 1480,
-kSingleOriginInTimingAllowOrigin = 1481,
-kMultipleOriginsInTimingAllowOrigin = 1482,
-kStarInTimingAllowOrigin = 1483,
-kSVGSMILAdditiveAnimation = 1484,
-kSendBeaconWithNonSimpleContentType = 1485,
-kChromeLoadTimesRequestTime = 1486,
-kChromeLoadTimesStartLoadTime = 1487,
-kChromeLoadTimesCommitLoadTime = 1488,
-kChromeLoadTimesFinishDocumentLoadTime = 1489,
-kChromeLoadTimesFinishLoadTime = 1490,
-kChromeLoadTimesFirstPaintTime = 1491,
-kChromeLoadTimesFirstPaintAfterLoadTime = 1492,
-kChromeLoadTimesNavigationType = 1493,
-kChromeLoadTimesWasFetchedViaSpdy = 1494,
-kChromeLoadTimesWasNpnNegotiated = 1495,
-kChromeLoadTimesNpnNegotiatedProtocol = 1496,
-kChromeLoadTimesWasAlternateProtocolAvailable = 1497,
-kChromeLoadTimesConnectionInfo = 1498,
-kChromeLoadTimesUnknown = 1499,
-kSVGViewElement = 1500,
-kWebShareShare = 1501,
-kAuxclickAddListenerCount = 1502,
-kHTMLCanvasElement = 1503,
-kSVGSMILAnimationElementTiming = 1504,
-kSVGSMILBeginEndAnimationElement = 1505,
-kSVGSMILPausing = 1506,
-kSVGSMILCurrentTime = 1507,
-kHTMLBodyElementOnSelectionChangeAttribute = 1508,
-kForeignFetchInterception = 1509,
-kUsbGetDevices = 1519,
-kUsbRequestDevice = 1520,
-kUsbDeviceOpen = 1521,
-kUsbDeviceClose = 1522,
-kUsbDeviceSelectConfiguration = 1523,
-kUsbDeviceClaimInterface = 1524,
-kUsbDeviceReleaseInterface = 1525,
-kUsbDeviceSelectAlternateInterface = 1526,
-kUsbDeviceControlTransferIn = 1527,
-kUsbDeviceControlTransferOut = 1528,
-kUsbDeviceClearHalt = 1529,
-kUsbDeviceTransferIn = 1530,
-kUsbDeviceTransferOut = 1531,
-kUsbDeviceIsochronousTransferIn = 1532,
-kUsbDeviceIsochronousTransferOut = 1533,
-kUsbDeviceReset = 1534,
-// The above items are available in M54 branch
-
-kPointerEnterLeaveFired = 1535,
-kPointerOverOutFired = 1536,
-kDraggableAttribute = 1539,
-kCleanScriptElementWithNonce = 1540,
-kPotentiallyInjectedScriptElementWithNonce = 1541,
-kPendingStylesheetAddedAfterBodyStarted = 1542,
-kUntrustedMouseDownEventDispatchedToSelect = 1543,
-kBlockedSniffingAudioToScript = 1544,
-kBlockedSniffingVideoToScript = 1545,
-kBlockedSniffingCSVToScript = 1546,
-kMetaSetCookie = 1547,
-kMetaRefresh = 1548,
-kMetaSetCookieWhenCSPBlocksInlineScript = 1549,
-kMetaRefreshWhenCSPBlocksInlineScript = 1550,
-kMiddleClickAutoscrollStart = 1551,
-kRTCPeerConnectionCreateOfferOptionsOfferToReceive = 1553,
-kDragAndDropScrollStart = 1554,
-kPresentationConnectionListConnectionAvailableEventListener = 1555,
-kWebAudioAutoplayCrossOriginIframe = 1556,
-kVRGetDisplays = 1558,
-kXSSAuditorBlockedScript = 1581,
-kXSSAuditorBlockedEntirePage = 1582,
-kXSSAuditorDisabled = 1583,
-kXSSAuditorEnabledFilter = 1584,
-kXSSAuditorEnabledBlock = 1585,
-kXSSAuditorInvalid = 1586,
-kTextInputEventOnInput = 1589,
-kTextInputEventOnTextArea = 1590,
-kTextInputEventOnContentEditable = 1591,
-kTextInputEventOnNotNode = 1592,
-kWebkitBeforeTextInsertedOnInput = 1593,
-kWebkitBeforeTextInsertedOnTextArea = 1594,
-kWebkitBeforeTextInsertedOnContentEditable = 1595,
-kWebkitBeforeTextInsertedOnNotNode = 1596,
-kWebkitEditableContentChangedOnInput = 1597,
-kWebkitEditableContentChangedOnTextArea = 1598,
-kWebkitEditableContentChangedOnContentEditable = 1599,
-kWebkitEditableContentChangedOnNotNode = 1600,
-kV8NavigatorUserMediaError_ConstraintName_AttributeGetter = 1601,
-kV8HTMLMediaElement_SrcObject_AttributeGetter = 1602,
-kV8HTMLMediaElement_SrcObject_AttributeSetter = 1603,
-kCreateObjectURLBlob = 1604,
-kCreateObjectURLMediaSource = 1605,
-kCreateObjectURLMediaStream = 1606,
-kDocumentCreateTouchWindowNull = 1607,
-kDocumentCreateTouchWindowWrongType = 1608,
-kDocumentCreateTouchTargetNull = 1609,
-kDocumentCreateTouchTargetWrongType = 1610,
-kDocumentCreateTouchMoreThanSevenArguments = 1612,
-kLongTaskObserver = 1615,
-kCSSOffsetInEffect = 1617,
-// The above items are available in M55 branch
-
-kVRGetDisplaysInsecureOrigin = 1618,
-kVRRequestPresent = 1619,
-kVRRequestPresentInsecureOrigin = 1620,
-kVRDeprecatedFieldOfView = 1621,
-kVideoInCanvas = 1622,
-kHiddenAutoplayedVideoInCanvas = 1623,
-kOffscreenCanvas = 1624,
-kGamepadPose = 1625,
-kGamepadHand = 1626,
-kGamepadDisplayId = 1627,
-kGamepadButtonTouched = 1628,
-kGamepadPoseHasOrientation = 1629,
-kGamepadPoseHasPosition = 1630,
-kGamepadPosePosition = 1631,
-kGamepadPoseLinearVelocity = 1632,
-kGamepadPoseLinearAcceleration = 1633,
-kGamepadPoseOrientation = 1634,
-kGamepadPoseAngularVelocity = 1635,
-kGamepadPoseAngularAcceleration = 1636,
-kV8RTCDataChannel_MaxRetransmitTime_AttributeGetter = 1638,
-kV8RTCDataChannel_MaxRetransmits_AttributeGetter = 1639,
-kV8RTCDataChannel_Reliable_AttributeGetter = 1640,
-kV8RTCPeerConnection_AddStream_Method = 1641,
-kV8RTCPeerConnection_CreateDTMFSender_Method = 1642,
-kV8RTCPeerConnection_GetLocalStreams_Method = 1643,
-kV8RTCPeerConnection_GetRemoteStreams_Method = 1644,
-kV8RTCPeerConnection_GetStreamById_Method = 1645,
-kV8RTCPeerConnection_RemoveStream_Method = 1646,
-kRTCPeerConnectionCreateDataChannelMaxRetransmitTime = 1648,
-kRTCPeerConnectionCreateDataChannelMaxRetransmits = 1649,
-kAudioContextCreateConstantSource = 1650,
-kWebAudioConstantSourceNode = 1651,
-kLoopbackEmbeddedInSecureContext = 1652,
-kLoopbackEmbeddedInNonSecureContext = 1653,
-kBlinkMacSystemFont = 1654,
-kRTCIceServerURL = 1656,
-kRTCIceServerURLs = 1657,
-kOffscreenCanvasTransferToImageBitmap2D = 1658,
-kOffscreenCanvasTransferToImageBitmapWebGL = 1659,
-kOffscreenCanvasCommit2D = 1660,
-kOffscreenCanvasCommitWebGL = 1661,
-kRTCConfigurationIceTransportPolicy = 1662,
-kRTCConfigurationIceTransports = 1664,
-kDocumentFullscreenElementInV0Shadow = 1665,
-kScriptWithCSPBypassingSchemeParserInserted = 1666,
-kScriptWithCSPBypassingSchemeNotParserInserted = 1667,
-kDocumentCreateElement2ndArgStringHandling = 1668,
-kV8MediaRecorder_Start_Method = 1669,
-kWebBluetoothRequestDevice = 1670,
-kUnitlessPerspectiveInPerspectiveProperty = 1671,
-kUnitlessPerspectiveInTransformProperty = 1672,
-kV8RTCSessionDescription_Type_AttributeGetter = 1673,
-kV8RTCSessionDescription_Type_AttributeSetter = 1674,
-kV8RTCSessionDescription_Sdp_AttributeGetter = 1675,
-kV8RTCSessionDescription_Sdp_AttributeSetter = 1676,
-kRTCSessionDescriptionInitNoType = 1677,
-kRTCSessionDescriptionInitNoSdp = 1678,
-kHTMLMediaElementPreloadForcedMetadata = 1679,
-kGenericSensorStart = 1680,
-kGenericSensorStop = 1681,
-kTouchEventPreventedNoTouchAction = 1682,
-kTouchEventPreventedForcedDocumentPassiveNoTouchAction = 1683,
-kV8Event_StopPropagation_Method = 1684,
-kV8Event_StopImmediatePropagation_Method = 1685,
-kImageCaptureConstructor = 1686,
-kV8Document_RootScroller_AttributeGetter = 1687,
-kV8Document_RootScroller_AttributeSetter = 1688,
-kCustomElementRegistryDefine = 1689,
-kLinkHeaderServiceWorker = 1690,
-kCSSShadowPiercingDescendantCombinator = 1691,
-// The above items are available in M56 branch.
-
-kCSSFlexibleBox = 1692,
-kCSSGridLayout = 1693,
-kFullscreenAllowedByOrientationChange = 1696,
-kServiceWorkerRespondToNavigationRequestWithRedirectedResponse = 1697,
-kV8AudioContext_Constructor = 1698,
-kV8OfflineAudioContext_Constructor = 1699,
-kAppInstalledEventAddListener = 1700,
-kAudioContextGetOutputTimestamp = 1701,
-kV8MediaStreamAudioDestinationNode_Constructor = 1702,
-kV8AnalyserNode_Constructor = 1703,
-kV8AudioBuffer_Constructor = 1704,
-kV8AudioBufferSourceNode_Constructor = 1705,
-kV8AudioProcessingEvent_Constructor = 1706,
-kV8BiquadFilterNode_Constructor = 1707,
-kV8ChannelMergerNode_Constructor = 1708,
-kV8ChannelSplitterNode_Constructor = 1709,
-kV8ConstantSourceNode_Constructor = 1710,
-kV8ConvolverNode_Constructor = 1711,
-kV8DelayNode_Constructor = 1712,
-kV8DynamicsCompressorNode_Constructor = 1713,
-kV8GainNode_Constructor = 1714,
-kV8IIRFilterNode_Constructor = 1715,
-kV8MediaElementAudioSourceNode_Constructor = 1716,
-kV8MediaStreamAudioSourceNode_Constructor = 1717,
-kV8OfflineAudioCompletionEvent_Constructor = 1718,
-kV8OscillatorNode_Constructor = 1719,
-kV8PannerNode_Constructor = 1720,
-kV8PeriodicWave_Constructor = 1721,
-kV8StereoPannerNode_Constructor = 1722,
-kV8WaveShaperNode_Constructor = 1723,
-kV8Headers_GetAll_Method = 1724,
-kNavigatorVibrateEngagementNone = 1725,
-kNavigatorVibrateEngagementMinimal = 1726,
-kNavigatorVibrateEngagementLow = 1727,
-kNavigatorVibrateEngagementMedium = 1728,
-kNavigatorVibrateEngagementHigh = 1729,
-kNavigatorVibrateEngagementMax = 1730,
-kAlertEngagementNone = 1731,
-kAlertEngagementMinimal = 1732,
-kAlertEngagementLow = 1733,
-kAlertEngagementMedium = 1734,
-kAlertEngagementHigh = 1735,
-kAlertEngagementMax = 1736,
-kConfirmEngagementNone = 1737,
-kConfirmEngagementMinimal = 1738,
-kConfirmEngagementLow = 1739,
-kConfirmEngagementMedium = 1740,
-kConfirmEngagementHigh = 1741,
-kConfirmEngagementMax = 1742,
-kPromptEngagementNone = 1743,
-kPromptEngagementMinimal = 1744,
-kPromptEngagementLow = 1745,
-kPromptEngagementMedium = 1746,
-kPromptEngagementHigh = 1747,
-kPromptEngagementMax = 1748,
-kTopNavInSandbox = 1749,
-kTopNavInSandboxWithoutGesture = 1750,
-kTopNavInSandboxWithPerm = 1751,
-kTopNavInSandboxWithPermButNoGesture = 1752,
-kReferrerPolicyHeader = 1753,
-kHTMLAnchorElementReferrerPolicyAttribute = 1754,
-kHTMLIFrameElementReferrerPolicyAttribute = 1755,
-kHTMLImageElementReferrerPolicyAttribute = 1756,
-kHTMLLinkElementReferrerPolicyAttribute = 1757,
-kBaseElement = 1758,
-kBaseWithCrossOriginHref = 1759,
-kBaseWithDataHref = 1760,
-kBaseWithNewlinesInTarget = 1761,
-kBaseWithOpenBracketInTarget = 1762,
-kBaseWouldBeBlockedByDefaultSrc = 1763,
-kV8AssigmentExpressionLHSIsCallInSloppy = 1764,
-kV8AssigmentExpressionLHSIsCallInStrict = 1765,
-kV8PromiseConstructorReturnedUndefined = 1766,
-kFormSubmittedWithUnclosedFormControl = 1767,
-kScrollbarUseVerticalScrollbarButton = 1777,
-kScrollbarUseVerticalScrollbarThumb = 1778,
-kScrollbarUseVerticalScrollbarTrack = 1779,
-kScrollbarUseHorizontalScrollbarButton = 1780,
-kScrollbarUseHorizontalScrollbarThumb = 1781,
-kScrollbarUseHorizontalScrollbarTrack = 1782,
-kHTMLTableCellElementColspan = 1783,
-kHTMLTableCellElementColspanGreaterThan1000 = 1784,
-kHTMLTableCellElementColspanGreaterThan8190 = 1785,
-kSelectionAddRangeIntersect = 1786,
-kPostMessageFromInsecureToSecureToplevel = 1787,
-// The above items are available in M57 branch.
-
-kV8MediaSession_Metadata_AttributeGetter = 1788,
-kV8MediaSession_Metadata_AttributeSetter = 1789,
-kV8MediaSession_PlaybackState_AttributeGetter = 1790,
-kV8MediaSession_PlaybackState_AttributeSetter = 1791,
-kV8MediaSession_SetActionHandler_Method = 1792,
-kWebNFCPush = 1793,
-kWebNFCCancelPush = 1794,
-kWebNFCWatch = 1795,
-kWebNFCCancelWatch = 1796,
-kAudioParamCancelAndHoldAtTime = 1797,
-kCSSValueUserModifyReadOnly = 1798,
-kCSSValueUserModifyReadWrite = 1799,
-kCSSValueUserModifyReadWritePlaintextOnly = 1800,
-kCSSValueOnDemand = 1802,
-kServiceWorkerNavigationPreload = 1803,
-kFullscreenRequestWithPendingElement = 1804,
-kHTMLIFrameElementAllowfullscreenAttributeSetAfterContentLoad = 1805,
-kPointerEventSetCaptureOutsideDispatch = 1806,
-kNotificationPermissionRequestedInsecureOrigin = 1807,
-kV8DeprecatedStorageInfo_QueryUsageAndQuota_Method = 1808,
-kV8DeprecatedStorageInfo_RequestQuota_Method = 1809,
-kV8DeprecatedStorageQuota_QueryUsageAndQuota_Method = 1810,
-kV8DeprecatedStorageQuota_RequestQuota_Method = 1811,
-kV8FileReaderSync_Constructor = 1812,
-kUncancelableTouchEventPreventDefaulted = 1813,
-kUncancelableTouchEventDueToMainThreadResponsivenessPreventDefaulted = 1814,
-kV8HTMLVideoElement_Poster_AttributeGetter = 1815,
-kV8HTMLVideoElement_Poster_AttributeSetter = 1816,
-kNotificationPermissionRequestedIframe = 1817,
-kPresentationReceiverInsecureOrigin = 1819,
-kPresentationReceiverSecureOrigin = 1820,
-kPresentationRequestInsecureOrigin = 1821,
-kPresentationRequestSecureOrigin = 1822,
-kRtcpMuxPolicyNegotiate = 1823,
-kDOMClobberedVariableAccessed = 1824,
-kHTMLDocumentCreateProcessingInstruction = 1825,
-kFetchResponseConstructionWithStream = 1826,
-kLocationOrigin = 1827,
-kDocumentOrigin = 1828,
-kCanvas2DFilter = 1830,
-kCanvas2DImageSmoothingQuality = 1831,
-kCanvasToBlob = 1832,
-kCanvasToDataURL = 1833,
-kOffscreenCanvasConvertToBlob = 1834,
-kSVGInCanvas2D = 1835,
-kSVGInWebGL = 1836,
-kSelectionFuncionsChangeFocus = 1837,
-kHTMLObjectElementGetter = 1838,
-kHTMLObjectElementSetter = 1839,
-kHTMLEmbedElementGetter = 1840,
-kHTMLEmbedElementSetter = 1841,
-kTransformUsesBoxSizeOnSVG = 1842,
-// The above items are available in M58 branch.
-
-kScrollByKeyboardArrowKeys = 1843,
-kScrollByKeyboardPageUpDownKeys = 1844,
-kScrollByKeyboardHomeEndKeys = 1845,
-kScrollByKeyboardSpacebarKey = 1846,
-kScrollByTouch = 1847,
-kScrollByWheel = 1848,
-kScheduledActionIgnored = 1849,
-kGetCanvas2DContextAttributes = 1850,
-kV8HTMLInputElement_Capture_AttributeGetter = 1851,
-kV8HTMLInputElement_Capture_AttributeSetter = 1852,
-kHTMLMediaElementControlsListAttribute = 1853,
-kHTMLMediaElementControlsListNoDownload = 1854,
-kHTMLMediaElementControlsListNoFullscreen = 1855,
-kHTMLMediaElementControlsListNoRemotePlayback = 1856,
-kPointerEventClickRetargetCausedByCapture = 1857,
-kVRDisplayDisplayName = 1861,
-kVREyeParametersOffset = 1862,
-kVRPoseLinearVelocity = 1863,
-kVRPoseLinearAcceleration = 1864,
-kVRPoseAngularVelocity = 1865,
-kVRPoseAngularAcceleration = 1866,
-kCSSOverflowPaged = 1867,
-kChildSrcAllowedWorkerThatScriptSrcBlocked = 1868,
-kHTMLTableElementPresentationAttributeBackground = 1869,
-kV8Navigator_GetInstalledRelatedApps_Method = 1870,
-kNamedAccessOnWindow_ChildBrowsingContext = 1871,
-kNamedAccessOnWindow_ChildBrowsingContext_CrossOriginNameMismatch = 1872,
-kV0CustomElementsRegisterHTMLCustomTag = 1873,
-kV0CustomElementsRegisterHTMLTypeExtension = 1874,
-kV0CustomElementsRegisterSVGElement = 1875,
-kV0CustomElementsRegisterEmbedderElement = 1876,
-kV0CustomElementsCreateCustomTagElement = 1877,
-kV0CustomElementsCreateTypeExtensionElement = 1878,
-kV0CustomElementsConstruct = 1879,
-kV8IDBObserver_Observe_Method = 1880,
-kV8IDBObserver_Unobserve_Method = 1881,
-kWebBluetoothRemoteCharacteristicGetDescriptor = 1882,
-kWebBluetoothRemoteCharacteristicGetDescriptors = 1883,
-kWebBluetoothRemoteCharacteristicReadValue = 1884,
-kWebBluetoothRemoteCharacteristicWriteValue = 1885,
-kWebBluetoothRemoteCharacteristicStartNotifications = 1886,
-kWebBluetoothRemoteCharacteristicStopNotifications = 1887,
-kWebBluetoothRemoteDescriptorReadValue = 1888,
-kWebBluetoothRemoteDescriptorWriteValue = 1889,
-kWebBluetoothRemoteServerConnect = 1890,
-kWebBluetoothRemoteServerDisconnect = 1891,
-kWebBluetoothRemoteServerGetPrimaryService = 1892,
-kWebBluetoothRemoteServerGetPrimaryServices = 1893,
-kWebBluetoothRemoteServiceGetCharacteristic = 1894,
-kWebBluetoothRemoteServiceGetCharacteristics = 1895,
-kHTMLContentElement = 1896,
-kHTMLShadowElement = 1897,
-kHTMLSlotElement = 1898,
-kAccelerometerConstructor = 1899,
-kAbsoluteOrientationSensorConstructor = 1900,
-kAmbientLightSensorConstructor = 1901,
-kGenericSensorOnActivate = 1902,
-kGenericSensorOnChange = 1903,
-kGenericSensorOnError = 1904,
-kGenericSensorActivated = 1905,
-kGyroscopeConstructor = 1906,
-kMagnetometerConstructor = 1907,
-kOrientationSensorPopulateMatrix = 1908,
-kWindowOpenWithInvalidURL = 1909,
-kCrossOriginMainFrameNulledNameAccessed = 1910,
-kMenuItemElementIconAttribute = 1911,
-kWebkitCSSMatrixSetMatrixValue = 1912,
-kWebkitCSSMatrixConstructFromString = 1913,
-kCanRequestURLHTTPContainingNewline = 1914,
-kGetGamepads = 1916,
-kV8SVGPathElement_GetPathSegAtLength_Method = 1917,
-kMediaStreamConstraintsAudio = 1918,
-kMediaStreamConstraintsAudioUnconstrained = 1919,
-kMediaStreamConstraintsVideo = 1920,
-kMediaStreamConstraintsVideoUnconstrained = 1921,
-kMediaStreamConstraintsWidth = 1922,
-kMediaStreamConstraintsHeight = 1923,
-kMediaStreamConstraintsAspectRatio = 1924,
-kMediaStreamConstraintsFrameRate = 1925,
-kMediaStreamConstraintsFacingMode = 1926,
-kMediaStreamConstraintsVolume = 1927,
-kMediaStreamConstraintsSampleRate = 1928,
-kMediaStreamConstraintsSampleSize = 1929,
-kMediaStreamConstraintsEchoCancellation = 1930,
-kMediaStreamConstraintsLatency = 1931,
-kMediaStreamConstraintsChannelCount = 1932,
-kMediaStreamConstraintsDeviceIdAudio = 1933,
-kMediaStreamConstraintsDeviceIdVideo = 1934,
-kMediaStreamConstraintsDisableLocalEcho = 1935,
-kMediaStreamConstraintsGroupIdAudio = 1936,
-kMediaStreamConstraintsGroupIdVideo = 1937,
-kMediaStreamConstraintsVideoKind = 1938,
-kMediaStreamConstraintsDepthNear = 1939,
-kMediaStreamConstraintsDepthFar = 1940,
-kMediaStreamConstraintsFocalLengthX = 1941,
-kMediaStreamConstraintsFocalLengthY = 1942,
-kMediaStreamConstraintsMediaStreamSourceAudio = 1943,
-kMediaStreamConstraintsMediaStreamSourceVideo = 1944,
-kMediaStreamConstraintsRenderToAssociatedSink = 1945,
-kMediaStreamConstraintsHotwordEnabled = 1946,
-kMediaStreamConstraintsGoogEchoCancellation = 1947,
-kMediaStreamConstraintsGoogExperimentalEchoCancellation = 1948,
-kMediaStreamConstraintsGoogAutoGainControl = 1949,
-kMediaStreamConstraintsGoogExperimentalAutoGainControl = 1950,
-kMediaStreamConstraintsGoogNoiseSuppression = 1951,
-kMediaStreamConstraintsGoogHighpassFilter = 1952,
-kMediaStreamConstraintsGoogTypingNoiseDetection = 1953,
-kMediaStreamConstraintsGoogExperimentalNoiseSuppression = 1954,
-kMediaStreamConstraintsGoogBeamforming = 1955,
-kMediaStreamConstraintsGoogArrayGeometry = 1956,
-kMediaStreamConstraintsGoogAudioMirroring = 1957,
-kMediaStreamConstraintsGoogDAEchoCancellation = 1958,
-kMediaStreamConstraintsGoogNoiseReduction = 1959,
-kMediaStreamConstraintsGoogPowerLineFrequency = 1960,
-// The above items are available in M59 branch.
-
-kViewportFixedPositionUnderFilter = 1961,
-kRequestMIDIAccessWithSysExOption = 1962,
-kRequestMIDIAccessIframeWithSysExOption = 1963,
-kGamepadAxes = 1964,
-kGamepadButtons = 1965,
-kVibrateWithoutUserGesture = 1966,
-kDispatchMouseEventOnDisabledFormControl = 1967,
-kElementNameDOMInvalidHTMLParserValid = 1968,
-kElementNameDOMValidHTMLParserInvalid = 1969,
-kGATTServerDisconnectedEvent = 1970,
-kAnchorClickDispatchForNonConnectedNode = 1971,
-kHTMLParseErrorNestedForm = 1972,
-kFontShapingNotDefGlyphObserved = 1973,
-kPostMessageOutgoingWouldBeBlockedByConnectSrc = 1974,
-kPostMessageIncomingWouldBeBlockedByConnectSrc = 1975,
-kPaymentRequestNetworkNameInSupportedMethods = 1976,
-kCrossOriginPropertyAccess = 1977,
-kCrossOriginPropertyAccessFromOpener = 1978,
-kCredentialManagerCreate = 1979,
-kWebDatabaseCreateDropFTS3Table = 1980,
-kFieldEditInSecureContext = 1981,
-kFieldEditInNonSecureContext = 1982,
-kCredentialManagerCredentialRequestOptionsUnmediated = 1983,
-kCredentialManagerGetMediationRequired = 1984,
-kCredentialManagerIdName = 1985,
-kCredentialManagerPasswordName = 1986,
-kCredentialManagerAdditionalData = 1987,
-kCredentialManagerCustomFetch = 1988,
-kNetInfoRtt = 1989,
-kNetInfoDownlink = 1990,
-kShapeDetection_BarcodeDetectorConstructor = 1991,
-kShapeDetection_FaceDetectorConstructor = 1992,
-kShapeDetection_TextDetectorConstructor = 1993,
-kCredentialManagerCredentialRequestOptionsOnlyUnmediated = 1994,
-kInertAttribute = 1995,
-kPluginInstanceAccessFromIsolatedWorld = 1996,
-kPluginInstanceAccessFromMainWorld = 1997,
-kRequestFullscreenForDialogElement = 1998,
-kRequestFullscreenForDialogElementInTopLayer = 1999,
-kShowModalForElementInFullscreenStack = 2000,
-kThreeValuedPositionBackground = 2001,
-kThreeValuedPositionBasicShape = 2002,
-kThreeValuedPositionGradient = 2003,
-kThreeValuedPositionObjectPosition = 2004,
-kThreeValuedPositionPerspectiveOrigin = 2005,
-kUnitlessZeroAngleFilter = 2007,
-kUnitlessZeroAngleGradient = 2008,
-kUnitlessZeroAngleTransform = 2010,
-kHTMLOListElementStartGetterReversedWithoutStartAttribute = 2011,
-kCredentialManagerPreventSilentAccess = 2012,
-kNetInfoEffectiveType = 2013,
-kV8SpeechRecognition_Start_Method = 2014,
-kTableRowDirectionDifferentFromTable = 2015,
-kTableSectionDirectionDifferentFromTable = 2016,
-// The above items are available in M60 branch.
-
-kClientHintsDeviceRAM = 2017,
-kCSSRegisterProperty = 2018,
-kRelativeOrientationSensorConstructor = 2019,
-kSmoothScrollJSInterventionActivated = 2020,
-kBudgetAPIGetCost = 2021,
-kBudgetAPIGetBudget = 2022,
-kCrossOriginMainFrameNulledNonEmptyNameAccessed = 2023,
-
-// Add new features immediately above this line. Don't change assigned
-// numbers of any item, and don't reuse removed slots.
-// Also, run update_use_counter_feature_enum.py in
-// chromium/src/tools/metrics/histograms/ to update the UMA mapping.
-kNumberOfFeatures,  // This enum value must be last.
diff --git a/third_party/WebKit/public/platform/WebFeature.h b/third_party/WebKit/public/platform/WebFeature.h
index 348447f..a251382 100644
--- a/third_party/WebKit/public/platform/WebFeature.h
+++ b/third_party/WebKit/public/platform/WebFeature.h
@@ -2,13 +2,1568 @@
 #define WebFeature_h
 
 namespace blink {
-
+// ============ Definition for WebFeature used for UseCounter ===============
+//
+// Do not change assigned numbers of existing items: add new features
+// to the end of the list.
+//
 // A WebFeature conceptually represents some particular web-exposed API
 // or code path which can be used/triggered by a web page.
 // TODO(rbyers): Add CSS and animated CSS feature types by making this a
 // more sophisticated class.
 enum class WebFeature : uint32_t {
-#include "UseCounterFeature.def"
+  kOBSOLETE_PageDestruction = 0,
+  kWorkerStart = 4,
+  kSharedWorkerStart = 5,
+  kUnprefixedIndexedDB = 9,
+  kOpenWebDatabase = 10,
+  kUnprefixedRequestAnimationFrame = 13,
+  kPrefixedRequestAnimationFrame = 14,
+  kContentSecurityPolicy = 15,
+  kContentSecurityPolicyReportOnly = 16,
+  kPrefixedTransitionEndEvent = 18,
+  kUnprefixedTransitionEndEvent = 19,
+  kPrefixedAndUnprefixedTransitionEndEvent = 20,
+  kAutoFocusAttribute = 21,
+  kDataListElement = 23,
+  kFormAttribute = 24,
+  kIncrementalAttribute = 25,
+  kInputTypeColor = 26,
+  kInputTypeDate = 27,
+  kInputTypeDateTimeFallback = 29,
+  kInputTypeDateTimeLocal = 30,
+  kInputTypeEmail = 31,
+  kInputTypeMonth = 32,
+  kInputTypeNumber = 33,
+  kInputTypeRange = 34,
+  kInputTypeSearch = 35,
+  kInputTypeTel = 36,
+  kInputTypeTime = 37,
+  kInputTypeURL = 38,
+  kInputTypeWeek = 39,
+  kInputTypeWeekFallback = 40,
+  kListAttribute = 41,
+  kMaxAttribute = 42,
+  kMinAttribute = 43,
+  kPatternAttribute = 44,
+  kPlaceholderAttribute = 45,
+  kPrefixedDirectoryAttribute = 47,
+  kRequiredAttribute = 49,
+  kStepAttribute = 51,
+  kPageVisits = 52,
+  kHTMLMarqueeElement = 53,
+  kReflection = 55,
+  kPrefixedStorageInfo = 57,
+  kDeprecatedFlexboxWebContent = 61,
+  kDeprecatedFlexboxChrome = 62,
+  kDeprecatedFlexboxChromeExtension = 63,
+  kUnprefixedPerformanceTimeline = 65,
+  kUnprefixedUserTiming = 67,
+  kWindowEvent = 69,
+  kContentSecurityPolicyWithBaseElement = 70,
+  kDocumentClear = 74,
+  kXMLDocument = 77,
+  kXSLProcessingInstruction = 78,
+  kXSLTProcessor = 79,
+  kSVGSwitchElement = 80,
+  kDocumentAll = 83,
+  kFormElement = 84,
+  kDemotedFormElement = 85,
+  kSVGAnimationElement = 90,
+  kLineClamp = 96,
+  kSubFrameBeforeUnloadRegistered = 97,
+  kSubFrameBeforeUnloadFired = 98,
+  kConsoleMarkTimeline = 102,
+  kDocumentCreateAttribute = 111,
+  kDocumentCreateAttributeNS = 112,
+  kDocumentXMLEncoding = 115,    // Removed from DOM4.
+  kDocumentXMLStandalone = 116,  // Removed from DOM4.
+  kDocumentXMLVersion = 117,     // Removed from DOM4.
+  kNavigatorProductSub = 123,
+  kNavigatorVendor = 124,
+  kNavigatorVendorSub = 125,
+  kPrefixedAnimationEndEvent = 128,
+  kUnprefixedAnimationEndEvent = 129,
+  kPrefixedAndUnprefixedAnimationEndEvent = 130,
+  kPrefixedAnimationStartEvent = 131,
+  kUnprefixedAnimationStartEvent = 132,
+  kPrefixedAndUnprefixedAnimationStartEvent = 133,
+  kPrefixedAnimationIterationEvent = 134,
+  kUnprefixedAnimationIterationEvent = 135,
+  kPrefixedAndUnprefixedAnimationIterationEvent = 136,
+  kEventReturnValue = 137,  // Legacy IE extension.
+  kSVGSVGElement = 138,
+  kDOMSubtreeModifiedEvent = 143,
+  kDOMNodeInsertedEvent = 144,
+  kDOMNodeRemovedEvent = 145,
+  kDOMNodeRemovedFromDocumentEvent = 146,
+  kDOMNodeInsertedIntoDocumentEvent = 147,
+  kDOMCharacterDataModifiedEvent = 148,
+  kDocumentAllLegacyCall = 150,
+  kGetMatchedCSSRules = 155,
+  kPrefixedAudioDecodedByteCount = 164,
+  kPrefixedVideoDecodedByteCount = 165,
+  kPrefixedVideoSupportsFullscreen = 166,
+  kPrefixedVideoDisplayingFullscreen = 167,
+  kPrefixedVideoEnterFullscreen = 168,
+  kPrefixedVideoExitFullscreen = 169,
+  kPrefixedVideoEnterFullScreen = 170,
+  kPrefixedVideoExitFullScreen = 171,
+  kPrefixedVideoDecodedFrameCount = 172,
+  kPrefixedVideoDroppedFrameCount = 173,
+  kPrefixedElementRequestFullscreen = 176,
+  kPrefixedElementRequestFullScreen = 177,
+  kBarPropLocationbar = 178,
+  kBarPropMenubar = 179,
+  kBarPropPersonalbar = 180,
+  kBarPropScrollbars = 181,
+  kBarPropStatusbar = 182,
+  kBarPropToolbar = 183,
+  kInputTypeEmailMultiple = 184,
+  kInputTypeEmailMaxLength = 185,
+  kInputTypeEmailMultipleMaxLength = 186,
+  kInputTypeText = 190,
+  kInputTypeTextMaxLength = 191,
+  kInputTypePassword = 192,
+  kInputTypePasswordMaxLength = 193,
+  kPrefixedPageVisibility = 196,
+  kDocumentBeforeUnloadRegistered = 200,
+  kDocumentBeforeUnloadFired = 201,
+  kDocumentUnloadRegistered = 202,
+  kDocumentUnloadFired = 203,
+  kSVGLocatableNearestViewportElement = 204,
+  kSVGLocatableFarthestViewportElement = 205,
+  kSVGPointMatrixTransform = 209,
+  kDOMFocusInOutEvent = 211,
+  kFileGetLastModifiedDate = 212,
+  kHTMLElementInnerText = 213,
+  kHTMLElementOuterText = 214,
+  kReplaceDocumentViaJavaScriptURL = 215,
+  kElementPrefixedMatchesSelector = 217,
+  kCSSStyleSheetRules = 219,
+  kCSSStyleSheetAddRule = 220,
+  kCSSStyleSheetRemoveRule = 221,
+  // The above items are available in M33 branch.
+
+  kInitMessageEvent = 222,
+  kPrefixedDevicePixelRatioMediaFeature = 233,
+  kPrefixedMaxDevicePixelRatioMediaFeature = 234,
+  kPrefixedMinDevicePixelRatioMediaFeature = 235,
+  kPrefixedTransform3dMediaFeature = 237,
+  kPrefixedStorageQuota = 240,
+  kResetReferrerPolicy = 243,
+  // Case-insensitivity dropped from specification.
+  kCaseInsensitiveAttrSelectorMatch = 244,
+  kFormNameAccessForImageElement = 246,
+  kFormNameAccessForPastNamesMap = 247,
+  kFormAssociationByParser = 248,
+  kSVGSVGElementInDocument = 250,
+  kSVGDocumentRootElement = 251,
+  kWorkerSubjectToCSP = 257,
+  kWorkerAllowedByChildBlockedByScript = 258,
+  kDeprecatedWebKitGradient = 260,
+  kDeprecatedWebKitLinearGradient = 261,
+  kDeprecatedWebKitRepeatingLinearGradient = 262,
+  kDeprecatedWebKitRadialGradient = 263,
+  kDeprecatedWebKitRepeatingRadialGradient = 264,
+  // The above items are available in M34 branch.
+
+  kTextAutosizing = 274,
+  kHTMLAnchorElementPingAttribute = 276,
+  kSVGClassName = 279,
+  kHTMLMediaElementSeekToFragmentStart = 281,
+  kHTMLMediaElementPauseAtFragmentEnd = 282,
+  kPrefixedWindowURL = 283,
+  kWindowOrientation = 285,
+  kDocumentCaptureEvents = 287,
+  kDocumentReleaseEvents = 288,
+  kWindowCaptureEvents = 289,
+  kWindowReleaseEvents = 290,
+  kDocumentXPathCreateExpression = 295,
+  kDocumentXPathCreateNSResolver = 296,
+  kDocumentXPathEvaluate = 297,
+  kAnimationConstructorKeyframeListEffectObjectTiming = 300,
+  kAnimationConstructorKeyframeListEffectNoTiming = 302,
+  kPrefixedCancelAnimationFrame = 304,
+  kNamedNodeMapGetNamedItem = 306,
+  kNamedNodeMapSetNamedItem = 307,
+  kNamedNodeMapRemoveNamedItem = 308,
+  kNamedNodeMapItem = 309,
+  kNamedNodeMapGetNamedItemNS = 310,
+  kNamedNodeMapSetNamedItemNS = 311,
+  kNamedNodeMapRemoveNamedItemNS = 312,
+  kPrefixedDocumentIsFullscreen = 318,
+  kPrefixedDocumentCurrentFullScreenElement = 320,
+  kPrefixedDocumentCancelFullScreen = 321,
+  kPrefixedDocumentFullscreenEnabled = 322,
+  kPrefixedDocumentFullscreenElement = 323,
+  kPrefixedDocumentExitFullscreen = 324,
+  // The above items are available in M35 branch.
+
+  kSVGForeignObjectElement = 325,
+  kSelectionSetPosition = 327,
+  kAnimationFinishEvent = 328,
+  kSVGSVGElementInXMLDocument = 329,
+  kEventSrcElement = 343,
+  kEventCancelBubble = 344,
+  kEventPath = 345,
+  kNodeIteratorDetach = 347,
+  kEventGetReturnValueTrue = 350,
+  kEventGetReturnValueFalse = 351,
+  kEventSetReturnValueTrue = 352,
+  kEventSetReturnValueFalse = 353,
+  kWindowOffscreenBuffering = 356,
+  kWindowDefaultStatus = 357,
+  kWindowDefaultstatus = 358,
+  kPrefixedTransitionEventConstructor = 361,
+  kPrefixedMutationObserverConstructor = 362,
+  kNotificationPermission = 371,
+  kRangeDetach = 372,
+  kPrefixedFileRelativePath = 386,
+  kDocumentCaretRangeFromPoint = 387,
+  kElementScrollIntoViewIfNeeded = 389,
+  kRangeExpand = 393,
+  kHTMLImageElementX = 396,
+  kHTMLImageElementY = 397,
+  kSelectionBaseNode = 400,
+  kSelectionBaseOffset = 401,
+  kSelectionExtentNode = 402,
+  kSelectionExtentOffset = 403,
+  kSelectionType = 404,
+  kSelectionModify = 405,
+  kSelectionSetBaseAndExtent = 406,
+  kSelectionEmpty = 407,
+  kVTTCue = 409,
+  kVTTCueRender = 410,
+  kVTTCueRenderVertical = 411,
+  kVTTCueRenderSnapToLinesFalse = 412,
+  kVTTCueRenderLineNotAuto = 413,
+  kVTTCueRenderPositionNot50 = 414,
+  kVTTCueRenderSizeNot100 = 415,
+  kVTTCueRenderAlignNotCenter = 416,
+  // The above items are available in M36 branch.
+
+  kElementRequestPointerLock = 417,
+  kVTTCueRenderRtl = 418,
+  kPostMessageFromSecureToInsecure = 419,
+  kPostMessageFromInsecureToSecure = 420,
+  kDocumentExitPointerLock = 421,
+  kDocumentPointerLockElement = 422,
+  kPrefixedCursorZoomIn = 424,
+  kPrefixedCursorZoomOut = 425,
+  kTextEncoderConstructor = 429,
+  kTextEncoderEncode = 430,
+  kTextDecoderConstructor = 431,
+  kTextDecoderDecode = 432,
+  kFocusInOutEvent = 433,
+  kMouseEventMovementX = 434,
+  kMouseEventMovementY = 435,
+  kDocumentFonts = 440,
+  kMixedContentFormsSubmitted = 441,
+  kFormsSubmitted = 442,
+  kHTMLImports = 455,
+  kElementCreateShadowRoot = 456,
+  kDocumentRegisterElement = 457,
+  kEditingAppleInterchangeNewline = 458,
+  kEditingAppleConvertedSpace = 459,
+  kEditingApplePasteAsQuotation = 460,
+  kEditingAppleStyleSpanClass = 461,
+  kHTMLImportsAsyncAttribute = 463,
+  kXMLHttpRequestSynchronous = 465,
+  kCSSSelectorPseudoUnresolved = 466,
+  kCSSSelectorPseudoShadow = 467,
+  kCSSSelectorPseudoContent = 468,
+  kCSSSelectorPseudoHost = 469,
+  kCSSSelectorPseudoHostContext = 470,
+  kCSSDeepCombinator = 471,
+  // The above items are available in M37 branch.
+
+  kUseAsm = 473,
+  kDOMWindowOpen = 475,
+  kDOMWindowOpenFeatures = 476,
+  kAspectRatioFlexItem = 479,
+  kDetailsElement = 480,
+  kDialogElement = 481,
+  kMapElement = 482,
+  kMeterElement = 483,
+  kProgressElement = 484,
+  kWheelEventWheelDeltaX = 491,
+  kWheelEventWheelDeltaY = 492,
+  kWheelEventWheelDelta = 493,
+  kSendBeacon = 494,
+  kSendBeaconQuotaExceeded = 495,
+  kSVGSMILElementInDocument = 501,
+  kMouseEventOffsetX = 502,
+  kMouseEventOffsetY = 503,
+  kMouseEventX = 504,
+  kMouseEventY = 505,
+  kMouseEventFromElement = 506,
+  kMouseEventToElement = 507,
+  kRequestFileSystem = 508,
+  kRequestFileSystemWorker = 509,
+  kRequestFileSystemSyncWorker = 510,
+  kSVGStyleElementTitle = 519,
+  kPictureSourceSrc = 520,
+  // The above items are available in M38 branch.
+
+  kPicture = 521,
+  kSizes = 522,
+  kSrcsetXDescriptor = 523,
+  kSrcsetWDescriptor = 524,
+  kSelectionContainsNode = 525,
+  kXMLExternalResourceLoad = 529,
+  kMixedContentPrivateHostnameInPublicHostname = 530,
+  kLegacyProtocolEmbeddedAsSubresource = 531,
+  kRequestedSubresourceWithEmbeddedCredentials = 532,
+  kNotificationCreated = 533,
+  kNotificationClosed = 534,
+  kNotificationPermissionRequested = 535,
+  kConsoleTimeline = 538,
+  kConsoleTimelineEnd = 539,
+  kSRIElementWithMatchingIntegrityAttribute = 540,
+  kSRIElementWithNonMatchingIntegrityAttribute = 541,
+  kSRIElementWithUnparsableIntegrityAttribute = 542,
+  kV8Animation_StartTime_AttributeGetter = 545,
+  kV8Animation_StartTime_AttributeSetter = 546,
+  kV8Animation_CurrentTime_AttributeGetter = 547,
+  kV8Animation_CurrentTime_AttributeSetter = 548,
+  kV8Animation_PlaybackRate_AttributeGetter = 549,
+  kV8Animation_PlaybackRate_AttributeSetter = 550,
+  kV8Animation_PlayState_AttributeGetter = 551,
+  kV8Animation_Finish_Method = 552,
+  kV8Animation_Play_Method = 553,
+  kV8Animation_Pause_Method = 554,
+  kV8Animation_Reverse_Method = 555,
+  // The above items are available in M39 branch.
+
+  kBreakIterator = 556,
+  kScreenOrientationAngle = 557,
+  kScreenOrientationType = 558,
+  kScreenOrientationLock = 559,
+  kScreenOrientationUnlock = 560,
+  kGeolocationSecureOrigin = 561,
+  kGeolocationInsecureOrigin = 562,
+  kNotificationSecureOrigin = 563,
+  kNotificationInsecureOrigin = 564,
+  kNotificationShowEvent = 565,
+  kSVGTransformListConsolidate = 569,
+  kSVGAnimatedTransformListBaseVal = 570,
+  kQuotedAnimationName = 571,
+  kQuotedKeyframesRule = 572,
+  kSrcsetDroppedCandidate = 573,
+  kWindowPostMessage = 574,
+  kRenderRuby = 576,
+  kScriptElementWithInvalidTypeHasSrc = 578,
+  kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload = 581,
+  kCSSSelectorPseudoScrollbar = 582,
+  kCSSSelectorPseudoScrollbarButton = 583,
+  kCSSSelectorPseudoScrollbarThumb = 584,
+  kCSSSelectorPseudoScrollbarTrack = 585,
+  kCSSSelectorPseudoScrollbarTrackPiece = 586,
+  kLangAttribute = 587,
+  kLangAttributeOnHTML = 588,
+  kLangAttributeOnBody = 589,
+  kLangAttributeDoesNotMatchToUILocale = 590,
+  kInputTypeSubmit = 591,
+  kInputTypeSubmitWithValue = 592,
+  // The above items are available in M40 branch.
+
+  kSetReferrerPolicy = 593,
+  kTextWholeText = 599,
+  kNotificationCloseEvent = 603,
+  kStyleMedia = 606,
+  kStyleMediaType = 607,
+  kStyleMediaMatchMedium = 608,
+  kMixedContentPresent = 609,
+  kMixedContentBlockable = 610,
+  kMixedContentAudio = 611,
+  kMixedContentDownload = 612,
+  kMixedContentFavicon = 613,
+  kMixedContentImage = 614,
+  kMixedContentInternal = 615,
+  kMixedContentPlugin = 616,
+  kMixedContentPrefetch = 617,
+  kMixedContentVideo = 618,
+  kCSSSelectorPseudoFullScreenAncestor = 628,
+  kCSSSelectorPseudoFullScreen = 629,
+  kWebKitCSSMatrix = 630,
+  kAudioContextCreateAnalyser = 631,
+  kAudioContextCreateBiquadFilter = 632,
+  kAudioContextCreateBufferSource = 633,
+  kAudioContextCreateChannelMerger = 634,
+  kAudioContextCreateChannelSplitter = 635,
+  kAudioContextCreateConvolver = 636,
+  kAudioContextCreateDelay = 637,
+  kAudioContextCreateDynamicsCompressor = 638,
+  kAudioContextCreateGain = 639,
+  kAudioContextCreateMediaElementSource = 640,
+  kAudioContextCreateMediaStreamDestination = 641,
+  kAudioContextCreateMediaStreamSource = 642,
+  kAudioContextCreateOscillator = 643,
+  kAudioContextCreatePeriodicWave = 645,
+  kAudioContextCreateScriptProcessor = 646,
+  kAudioContextCreateStereoPanner = 647,
+  kAudioContextCreateWaveShaper = 648,
+  kAudioContextDecodeAudioData = 649,
+  kAudioContextResume = 650,
+  kAudioContextSuspend = 651,
+  kMixedContentInNonHTTPSFrameThatRestrictsMixedContent = 661,
+  kMixedContentInSecureFrameThatDoesNotRestrictMixedContent = 662,
+  kMixedContentWebSocket = 663,
+  kSyntheticKeyframesInCompositedCSSAnimation = 664,
+  kMixedContentFormPresent = 665,
+  kGetUserMediaInsecureOrigin = 666,
+  kGetUserMediaSecureOrigin = 667,
+  // The above items are available in M41 branch.
+
+  kDeviceMotionInsecureOrigin = 668,
+  kDeviceMotionSecureOrigin = 669,
+  kDeviceOrientationInsecureOrigin = 670,
+  kDeviceOrientationSecureOrigin = 671,
+  kSandboxViaIFrame = 672,
+  kSandboxViaCSP = 673,
+  kBlockedSniffingImageToScript = 674,
+  kFetch = 675,
+  kFetchBodyStream = 676,
+  kXMLHttpRequestAsynchronous = 677,
+  kWhiteSpacePreFromXMLSpace = 679,
+  kWhiteSpaceNowrapFromXMLSpace = 680,
+  kSVGSVGElementForceRedraw = 685,
+  kSVGSVGElementSuspendRedraw = 686,
+  kSVGSVGElementUnsuspendRedraw = 687,
+  kSVGSVGElementUnsuspendRedrawAll = 688,
+  kAudioContextClose = 689,
+  kCSSZoomNotEqualToOne = 691,
+  // The above items are available in M42 branch.
+
+  kClientRectListItem = 694,
+  kWindowClientInformation = 695,
+  kWindowFind = 696,
+  kWindowScreenLeft = 697,
+  kWindowScreenTop = 698,
+  kV8Animation_Cancel_Method = 699,
+  kV8Animation_Onfinish_AttributeGetter = 700,
+  kV8Animation_Onfinish_AttributeSetter = 701,
+  kV8Window_WebKitAnimationEvent_ConstructorGetter = 707,
+  kCryptoGetRandomValues = 710,
+  kSubtleCryptoEncrypt = 711,
+  kSubtleCryptoDecrypt = 712,
+  kSubtleCryptoSign = 713,
+  kSubtleCryptoVerify = 714,
+  kSubtleCryptoDigest = 715,
+  kSubtleCryptoGenerateKey = 716,
+  kSubtleCryptoImportKey = 717,
+  kSubtleCryptoExportKey = 718,
+  kSubtleCryptoDeriveBits = 719,
+  kSubtleCryptoDeriveKey = 720,
+  kSubtleCryptoWrapKey = 721,
+  kSubtleCryptoUnwrapKey = 722,
+  kCryptoAlgorithmAesCbc = 723,
+  kCryptoAlgorithmHmac = 724,
+  kCryptoAlgorithmRsaSsaPkcs1v1_5 = 725,
+  kCryptoAlgorithmSha1 = 726,
+  kCryptoAlgorithmSha256 = 727,
+  kCryptoAlgorithmSha384 = 728,
+  kCryptoAlgorithmSha512 = 729,
+  kCryptoAlgorithmAesGcm = 730,
+  kCryptoAlgorithmRsaOaep = 731,
+  kCryptoAlgorithmAesCtr = 732,
+  kCryptoAlgorithmAesKw = 733,
+  kCryptoAlgorithmRsaPss = 734,
+  kCryptoAlgorithmEcdsa = 735,
+  kCryptoAlgorithmEcdh = 736,
+  kCryptoAlgorithmHkdf = 737,
+  kCryptoAlgorithmPbkdf2 = 738,
+  kDocumentSetDomain = 739,
+  kUpgradeInsecureRequestsEnabled = 740,
+  kUpgradeInsecureRequestsUpgradedRequest = 741,
+  kDocumentDesignMode = 742,
+  kGlobalCacheStorage = 743,
+  kNetInfo = 744,
+  kBackgroundSync = 745,
+  kLegacyConst = 748,
+  kV8Permissions_Query_Method = 750,
+  // The above items are available in M43 branch.
+
+  kV8HTMLInputElement_Autocapitalize_AttributeGetter = 754,
+  kV8HTMLInputElement_Autocapitalize_AttributeSetter = 755,
+  kV8HTMLTextAreaElement_Autocapitalize_AttributeGetter = 756,
+  kV8HTMLTextAreaElement_Autocapitalize_AttributeSetter = 757,
+  kSVGHrefBaseVal = 758,
+  kSVGHrefAnimVal = 759,
+  kV8CSSRuleList_Item_Method = 760,
+  kV8MediaList_Item_Method = 761,
+  kV8StyleSheetList_Item_Method = 762,
+  kStyleSheetListAnonymousNamedGetter = 763,
+  kAutocapitalizeAttribute = 764,
+  kFullscreenSecureOrigin = 765,
+  kFullscreenInsecureOrigin = 766,
+  kDialogInSandboxedContext = 767,
+  kSVGSMILAnimationInImageRegardlessOfCache = 768,
+  kPerformanceFrameTiming = 772,
+  kV8Element_Animate_Method = 773,
+  // The above items are available in M44 branch.
+
+  kV8SVGSVGElement_GetElementById_Method = 778,
+  kElementCreateShadowRootMultiple = 779,
+  kV8MessageChannel_Constructor = 780,
+  kV8MessagePort_PostMessage_Method = 781,
+  kV8MessagePort_Start_Method = 782,
+  kV8MessagePort_Close_Method = 783,
+  kMessagePortsTransferred = 784,
+  kCSSKeyframesRuleAnonymousIndexedGetter = 785,
+  kV8Screen_AvailLeft_AttributeGetter = 786,
+  kV8Screen_AvailTop_AttributeGetter = 787,
+  kV8SVGFEConvolveMatrixElement_PreserveAlpha_AttributeGetter = 791,
+  kV8SVGStyleElement_Disabled_AttributeGetter = 798,
+  kV8SVGStyleElement_Disabled_AttributeSetter = 799,
+  kInputTypeFileSecureOrigin = 801,
+  kInputTypeFileInsecureOrigin = 802,
+  kElementAttachShadow = 804,
+  kV8SecurityPolicyViolationEvent_DocumentURI_AttributeGetter = 806,
+  kV8SecurityPolicyViolationEvent_BlockedURI_AttributeGetter = 807,
+  kV8SecurityPolicyViolationEvent_StatusCode_AttributeGetter = 808,
+  kHTMLLinkElementDisabled = 809,
+  kV8HTMLLinkElement_Disabled_AttributeGetter = 810,
+  kV8HTMLLinkElement_Disabled_AttributeSetter = 811,
+  kV8HTMLStyleElement_Disabled_AttributeGetter = 812,
+  kV8HTMLStyleElement_Disabled_AttributeSetter = 813,
+  kV8DOMError_Constructor = 816,
+  kV8DOMError_Name_AttributeGetter = 817,
+  kV8DOMError_Message_AttributeGetter = 818,
+  kTextInputFired = 830,
+  kV8TextEvent_Data_AttributeGetter = 831,
+  kV8TextEvent_InitTextEvent_Method = 832,
+  kClientHintsDPR = 835,
+  kClientHintsResourceWidth = 836,
+  kClientHintsViewportWidth = 837,
+  kSRIElementIntegrityAttributeButIneligible = 838,
+  kFormDataAppendNull = 843,
+  kNonHTMLElementSetAttributeNodeFromHTMLDocumentNameNotLowercase = 845,
+  kNavigatorVibrate = 850,
+  kNavigatorVibrateSubFrame = 851,
+  kV8XPathEvaluator_Constructor = 853,
+  kV8XPathEvaluator_CreateExpression_Method = 854,
+  kV8XPathEvaluator_CreateNSResolver_Method = 855,
+  kV8XPathEvaluator_Evaluate_Method = 856,
+  kRequestMIDIAccess = 857,
+  kV8MouseEvent_LayerX_AttributeGetter = 858,
+  kV8MouseEvent_LayerY_AttributeGetter = 859,
+  kInnerTextWithShadowTree = 860,
+  kSelectionToStringWithShadowTree = 861,
+  kWindowFindWithShadowTree = 862,
+  kV8CompositionEvent_InitCompositionEvent_Method = 863,
+  kV8CustomEvent_InitCustomEvent_Method = 864,
+  kV8DeviceMotionEvent_InitDeviceMotionEvent_Method = 865,
+  kV8DeviceOrientationEvent_InitDeviceOrientationEvent_Method = 866,
+  kV8Event_InitEvent_Method = 867,
+  kV8KeyboardEvent_InitKeyboardEvent_Method = 868,
+  kV8MouseEvent_InitMouseEvent_Method = 869,
+  kV8MutationEvent_InitMutationEvent_Method = 870,
+  kV8StorageEvent_InitStorageEvent_Method = 871,
+  kV8UIEvent_InitUIEvent_Method = 873,
+  kV8Document_CreateTouch_Method = 874,
+  kRequestFileSystemNonWebbyOrigin = 876,
+  kV8MemoryInfo_TotalJSHeapSize_AttributeGetter = 879,
+  kV8MemoryInfo_UsedJSHeapSize_AttributeGetter = 880,
+  kV8MemoryInfo_JSHeapSizeLimit_AttributeGetter = 881,
+  kV8Performance_Timing_AttributeGetter = 882,
+  kV8Performance_Navigation_AttributeGetter = 883,
+  kV8Performance_Memory_AttributeGetter = 884,
+  kV8SharedWorker_WorkerStart_AttributeGetter = 885,
+  // The above items are available in M45 branch.
+
+  kHTMLMediaElementPreloadNone = 892,
+  kHTMLMediaElementPreloadMetadata = 893,
+  kHTMLMediaElementPreloadAuto = 894,
+  kHTMLMediaElementPreloadDefault = 895,
+  kMixedContentBlockableAllowed = 896,
+  kPseudoBeforeAfterForInputElement = 897,
+  kV8Permissions_Revoke_Method = 898,
+  kLinkRelDnsPrefetch = 899,
+  kLinkRelPreconnect = 900,
+  kLinkRelPreload = 901,
+  kLinkHeaderDnsPrefetch = 902,
+  kLinkHeaderPreconnect = 903,
+  kClientHintsMetaAcceptCH = 904,
+  kHTMLElementDeprecatedWidth = 905,
+  kClientHintsContentDPR = 906,
+  kElementAttachShadowOpen = 907,
+  kElementAttachShadowClosed = 908,
+  kAudioParamSetValueAtTime = 909,
+  kAudioParamLinearRampToValueAtTime = 910,
+  kAudioParamExponentialRampToValueAtTime = 911,
+  kAudioParamSetTargetAtTime = 912,
+  kAudioParamSetValueCurveAtTime = 913,
+  kAudioParamCancelScheduledValues = 914,
+  kV8Permissions_Request_Method = 915,
+  kLinkRelPrefetch = 917,
+  kLinkRelPrerender = 918,
+  kLinkRelNext = 919,
+  kCSSValuePrefixedMinContent = 921,
+  kCSSValuePrefixedMaxContent = 922,
+  kCSSValuePrefixedFitContent = 923,
+  kCSSValuePrefixedFillAvailable = 924,
+  kPresentationDefaultRequest = 926,
+  kPresentationAvailabilityChangeEventListener = 927,
+  kPresentationRequestConstructor = 928,
+  kPresentationRequestStart = 929,
+  kPresentationRequestReconnect = 930,
+  kPresentationRequestGetAvailability = 931,
+  kPresentationRequestConnectionAvailableEventListener = 932,
+  kPresentationConnectionTerminate = 933,
+  kPresentationConnectionSend = 934,
+  kPresentationConnectionMessageEventListener = 936,
+  kCSSAnimationsStackedNeutralKeyframe = 937,
+  kReadingCheckedInClickHandler = 938,
+  kFlexboxIntrinsicSizeAlgorithmIsDifferent = 939,
+  // The above items are available in M46 branch.
+
+  kHTMLImportsHasStyleSheets = 940,
+  kNetInfoType = 946,
+  kNetInfoDownlinkMax = 947,
+  kNetInfoOnChange = 948,
+  kNetInfoOnTypeChange = 949,
+  kV8Window_Alert_Method = 950,
+  kV8Window_Confirm_Method = 951,
+  kV8Window_Prompt_Method = 952,
+  kV8Window_Print_Method = 953,
+  kV8Window_RequestIdleCallback_Method = 954,
+  kFlexboxPercentagePaddingVertical = 955,
+  kFlexboxPercentageMarginVertical = 956,
+  kBackspaceNavigatedBack = 957,
+  kBackspaceNavigatedBackAfterFormInteraction = 958,
+  kCSPSourceWildcardWouldMatchExactHost = 959,
+  kCredentialManagerGet = 960,
+  kCredentialManagerGetMediationOptional = 961,
+  kCredentialManagerGetMediationSilent = 962,
+  kCredentialManagerStore = 963,
+  kCredentialManagerRequireUserMediation = 964,
+  // The above items are available in M47 branch.
+
+  kBlockableMixedContentInSubframeBlocked = 966,
+  kAddEventListenerThirdArgumentIsObject = 967,
+  kRemoveEventListenerThirdArgumentIsObject = 968,
+  kCSSAtRuleCharset = 969,
+  kCSSAtRuleFontFace = 970,
+  kCSSAtRuleImport = 971,
+  kCSSAtRuleKeyframes = 972,
+  kCSSAtRuleMedia = 973,
+  kCSSAtRuleNamespace = 974,
+  kCSSAtRulePage = 975,
+  kCSSAtRuleSupports = 976,
+  kCSSAtRuleViewport = 977,
+  kCSSAtRuleWebkitKeyframes = 978,
+  kV8HTMLFieldSetElement_Elements_AttributeGetter = 979,
+  kHTMLMediaElementPreloadForcedNone = 980,
+  kExternalAddSearchProvider = 981,
+  kExternalIsSearchProviderInstalled = 982,
+  kV8Permissions_RequestAll_Method = 983,
+  kDeviceOrientationAbsoluteInsecureOrigin = 987,
+  kDeviceOrientationAbsoluteSecureOrigin = 988,
+  kFontFaceConstructor = 989,
+  kServiceWorkerControlledPage = 990,
+  kMeterElementWithMeterAppearance = 993,
+  kMeterElementWithNoneAppearance = 994,
+  kSelectionAnchorNode = 997,
+  kSelectionAnchorOffset = 998,
+  kSelectionFocusNode = 999,
+  kSelectionFocusOffset = 1000,
+  kSelectionIsCollapsed = 1001,
+  kSelectionRangeCount = 1002,
+  kSelectionGetRangeAt = 1003,
+  kSelectionAddRange = 1004,
+  kSelectionRemoveAllRanges = 1005,
+  kSelectionCollapse = 1006,
+  kSelectionCollapseToStart = 1007,
+  kSelectionCollapseToEnd = 1008,
+  kSelectionExtend = 1009,
+  kSelectionSelectAllChildren = 1010,
+  kSelectionDeleteDromDocument = 1011,
+  kSelectionDOMString = 1012,
+  kInputTypeRangeVerticalAppearance = 1013,
+  // The above items are available in M48 branch.
+
+  kCSSFilterReference = 1014,
+  kCSSFilterGrayscale = 1015,
+  kCSSFilterSepia = 1016,
+  kCSSFilterSaturate = 1017,
+  kCSSFilterHueRotate = 1018,
+  kCSSFilterInvert = 1019,
+  kCSSFilterOpacity = 1020,
+  kCSSFilterBrightness = 1021,
+  kCSSFilterContrast = 1022,
+  kCSSFilterBlur = 1023,
+  kCSSFilterDropShadow = 1024,
+  kBackgroundSyncRegister = 1025,
+  kExecCommandOnInputOrTextarea = 1027,
+  kV8History_ScrollRestoration_AttributeGetter = 1028,
+  kV8History_ScrollRestoration_AttributeSetter = 1029,
+  kSVG1DOMFilter = 1030,
+  kOfflineAudioContextStartRendering = 1031,
+  kOfflineAudioContextSuspend = 1032,
+  kOfflineAudioContextResume = 1033,
+  kSVG1DOMPaintServer = 1035,
+  kSVGSVGElementFragmentSVGView = 1036,
+  kSVGSVGElementFragmentSVGViewElement = 1037,
+  kPresentationConnectionClose = 1038,
+  kSVG1DOMShape = 1039,
+  kSVG1DOMText = 1040,
+  kRTCPeerConnectionConstructorConstraints = 1041,
+  kRTCPeerConnectionConstructorCompliant = 1042,
+  kRTCPeerConnectionCreateOfferLegacyFailureCallback = 1044,
+  kRTCPeerConnectionCreateOfferLegacyConstraints = 1045,
+  kRTCPeerConnectionCreateOfferLegacyOfferOptions = 1046,
+  kRTCPeerConnectionCreateOfferLegacyCompliant = 1047,
+  kRTCPeerConnectionCreateAnswerLegacyFailureCallback = 1049,
+  kRTCPeerConnectionCreateAnswerLegacyConstraints = 1050,
+  kRTCPeerConnectionCreateAnswerLegacyCompliant = 1051,
+  kRTCPeerConnectionSetLocalDescriptionLegacyNoSuccessCallback = 1052,
+  kRTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback = 1053,
+  kRTCPeerConnectionSetLocalDescriptionLegacyCompliant = 1054,
+  kRTCPeerConnectionSetRemoteDescriptionLegacyNoSuccessCallback = 1055,
+  kRTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback = 1056,
+  kRTCPeerConnectionSetRemoteDescriptionLegacyCompliant = 1057,
+  kRTCPeerConnectionGetStatsLegacyNonCompliant = 1058,
+  kNodeFilterIsFunction = 1059,
+  kNodeFilterIsObject = 1060,
+  kCSSSelectorInternalPseudoListBox = 1062,
+  kCSSSelectorInternalMediaControlsOverlayCastButton = 1064,
+  kCSSSelectorInternalPseudoSpatialNavigationFocus = 1065,
+  kSameOriginTextScript = 1066,
+  kSameOriginApplicationScript = 1067,
+  kSameOriginOtherScript = 1068,
+  kCrossOriginTextScript = 1069,
+  kCrossOriginApplicationScript = 1070,
+  kCrossOriginOtherScript = 1071,
+  kSVG1DOMSVGTests = 1072,
+  kDisableRemotePlaybackAttribute = 1074,
+  kV8SloppyMode = 1075,
+  kV8StrictMode = 1076,
+  kV8StrongMode = 1077,
+  kAudioNodeConnectToAudioNode = 1078,
+  kAudioNodeConnectToAudioParam = 1079,
+  kAudioNodeDisconnectFromAudioNode = 1080,
+  kAudioNodeDisconnectFromAudioParam = 1081,
+  kV8CSSFontFaceRule_Style_AttributeGetter = 1082,
+  kSelectionCollapseNull = 1083,
+  kSelectionSetBaseAndExtentNull = 1084,
+  kV8SVGSVGElement_CreateSVGNumber_Method = 1085,
+  kV8SVGSVGElement_CreateSVGLength_Method = 1086,
+  kV8SVGSVGElement_CreateSVGAngle_Method = 1087,
+  kV8SVGSVGElement_CreateSVGPoint_Method = 1088,
+  kV8SVGSVGElement_CreateSVGMatrix_Method = 1089,
+  kV8SVGSVGElement_CreateSVGRect_Method = 1090,
+  kV8SVGSVGElement_CreateSVGTransform_Method = 1091,
+  kV8SVGSVGElement_CreateSVGTransformFromMatrix_Method = 1092,
+  kFormNameAccessForNonDescendantImageElement = 1093,
+  kV8RegExpPrototypeStickyGetter = 1096,
+  kV8RegExpPrototypeToString = 1097,
+  kV8InputDeviceCapabilities_FiresTouchEvents_AttributeGetter = 1098,
+  kDataElement = 1099,
+  kTimeElement = 1100,
+  kSVG1DOMUriReference = 1101,
+  kSVG1DOMZoomAndPan = 1102,
+  kV8SVGGraphicsElement_Transform_AttributeGetter = 1103,
+  kMenuItemElement = 1104,
+  kMenuItemCloseTag = 1105,
+  kSVG1DOMMarkerElement = 1106,
+  kSVG1DOMUseElement = 1107,
+  kSVG1DOMMaskElement = 1108,
+  kV8SVGAElement_Target_AttributeGetter = 1109,
+  kV8SVGClipPathElement_ClipPathUnits_AttributeGetter = 1110,
+  kSVG1DOMFitToViewBox = 1111,
+  kSVG1DOMSVGElement = 1114,
+  kSVG1DOMImageElement = 1115,
+  kSVG1DOMForeignObjectElement = 1116,
+  kAudioContextCreateIIRFilter = 1117,
+  // The above items are available in M49 branch
+
+  kCSSSelectorPseudoSlotted = 1118,
+  kMediaDevicesEnumerateDevices = 1119,
+  kNonSecureSharedWorkerAccessedFromSecureContext = 1120,
+  kSecureSharedWorkerAccessedFromNonSecureContext = 1121,
+  kEventComposedPath = 1123,
+  kLinkHeaderPreload = 1124,
+  kMouseWheelEvent = 1125,
+  kWheelEvent = 1126,
+  kMouseWheelAndWheelEvent = 1127,
+  kBodyScrollsInAdditionToViewport = 1128,
+  kDocumentDesignModeEnabeld = 1129,
+  kContentEditableTrue = 1130,
+  kContentEditableTrueOnHTML = 1131,
+  kContentEditablePlainTextOnly = 1132,
+  kV8RegExpPrototypeUnicodeGetter = 1133,
+  kV8IntlV8Parse = 1134,
+  kV8IntlPattern = 1135,
+  kV8IntlResolved = 1136,
+  kV8PromiseChain = 1137,
+  kV8PromiseAccept = 1138,
+  kV8PromiseDefer = 1139,
+  kEventComposed = 1140,
+  kGeolocationInsecureOriginIframe = 1141,
+  kGeolocationSecureOriginIframe = 1142,
+  kRequestMIDIAccessIframe = 1143,
+  kGetUserMediaInsecureOriginIframe = 1144,
+  kGetUserMediaSecureOriginIframe = 1145,
+  kElementRequestPointerLockIframe = 1146,
+  kNotificationAPIInsecureOriginIframe = 1147,
+  kNotificationAPISecureOriginIframe = 1148,
+  kWebSocket = 1149,
+  kMediaStreamConstraintsNameValue = 1150,
+  kMediaStreamConstraintsFromDictionary = 1151,
+  kMediaStreamConstraintsConformant = 1152,
+  kCSSSelectorIndirectAdjacent = 1153,
+  kCreateImageBitmap = 1156,
+  kPresentationConnectionConnectEventListener = 1157,
+  kPresentationConnectionCloseEventListener = 1158,
+  kPresentationConnectionTerminateEventListener = 1159,
+  kDocumentCreateEventAnimationEvent = 1162,
+  kDocumentCreateEventBeforeUnloadEvent = 1166,
+  kDocumentCreateEventCompositionEvent = 1168,
+  kDocumentCreateEventDragEvent = 1169,
+  kDocumentCreateEventErrorEvent = 1170,
+  kDocumentCreateEventFocusEvent = 1171,
+  kDocumentCreateEventHashChangeEvent = 1172,
+  kDocumentCreateEventMutationEvent = 1173,
+  kDocumentCreateEventPageTransitionEvent = 1174,
+  kDocumentCreateEventPopStateEvent = 1176,
+  kDocumentCreateEventTextEvent = 1182,
+  kDocumentCreateEventTransitionEvent = 1183,
+  kDocumentCreateEventWheelEvent = 1184,
+  kDocumentCreateEventTrackEvent = 1186,
+  kDocumentCreateEventMutationEvents = 1188,
+  kDocumentCreateEventSVGEvents = 1190,
+  kDocumentCreateEventDeviceMotionEvent = 1195,
+  kDocumentCreateEventDeviceOrientationEvent = 1196,
+  kDocumentCreateEventIDBVersionChangeEvent = 1201,
+  kDocumentCreateEventStorageEvent = 1221,
+  kDocumentCreateEventWebGLContextEvent = 1224,
+  kDocumentCreateEventCloseEvent = 1227,
+  kDocumentCreateEventKeyboardEvents = 1228,
+  kHTMLMediaElement = 1229,
+  kHTMLMediaElementInDocument = 1230,
+  kHTMLMediaElementControlsAttribute = 1231,
+  kV8Animation_Oncancel_AttributeGetter = 1233,
+  kV8Animation_Oncancel_AttributeSetter = 1234,
+  kV8HTMLCommentInExternalScript = 1235,
+  kV8HTMLComment = 1236,
+  kV8SloppyModeBlockScopedFunctionRedefinition = 1237,
+  kV8ForInInitializer = 1238,
+  kV8Animation_Id_AttributeGetter = 1239,
+  kV8Animation_Id_AttributeSetter = 1240,
+  kApplicationCacheManifestSelectInsecureOrigin = 1245,
+  kApplicationCacheManifestSelectSecureOrigin = 1246,
+  kApplicationCacheAPIInsecureOrigin = 1247,
+  kApplicationCacheAPISecureOrigin = 1248,
+  // The above items are available in M50 branch
+
+  kCSSAtRuleApply = 1249,
+  kCSSSelectorPseudoAny = 1250,
+  kDocumentAllItemNoArguments = 1252,
+  kDocumentAllItemNamed = 1253,
+  kDocumentAllItemIndexed = 1254,
+  kDocumentAllItemIndexedWithNonNumber = 1255,
+  kDocumentAllLegacyCallNoArguments = 1256,
+  kDocumentAllLegacyCallNamed = 1257,
+  kDocumentAllLegacyCallIndexed = 1258,
+  kDocumentAllLegacyCallIndexedWithNonNumber = 1259,
+  kDocumentAllLegacyCallTwoArguments = 1260,
+  kHTMLLabelElementControlForNonFormAssociatedElement = 1263,
+  kHTMLMediaElementLoadNetworkEmptyNotPaused = 1265,
+  kV8Window_WebkitSpeechGrammar_ConstructorGetter = 1267,
+  kV8Window_WebkitSpeechGrammarList_ConstructorGetter = 1268,
+  kV8Window_WebkitSpeechRecognition_ConstructorGetter = 1269,
+  kV8Window_WebkitSpeechRecognitionError_ConstructorGetter = 1270,
+  kV8Window_WebkitSpeechRecognitionEvent_ConstructorGetter = 1271,
+  kV8Window_SpeechSynthesis_AttributeGetter = 1272,
+  kV8IDBFactory_WebkitGetDatabaseNames_Method = 1273,
+  kImageDocument = 1274,
+  kScriptPassesCSPDynamic = 1275,
+  kCSPWithStrictDynamic = 1277,
+  kScrollAnchored = 1278,
+  kAddEventListenerFourArguments = 1279,
+  kRemoveEventListenerFourArguments = 1280,
+  kSVGCalcModeDiscrete = 1287,
+  kSVGCalcModeLinear = 1288,
+  kSVGCalcModePaced = 1289,
+  kSVGCalcModeSpline = 1290,
+  kFormSubmissionStarted = 1291,
+  kFormValidationStarted = 1292,
+  kFormValidationAbortedSubmission = 1293,
+  kFormValidationShowedMessage = 1294,
+  kWebAnimationsEasingAsFunctionLinear = 1295,
+  kWebAnimationsEasingAsFunctionOther = 1296,
+  // The above items are available in M51 branch
+
+  kV8Document_Images_AttributeGetter = 1297,
+  kV8Document_Embeds_AttributeGetter = 1298,
+  kV8Document_Plugins_AttributeGetter = 1299,
+  kV8Document_Links_AttributeGetter = 1300,
+  kV8Document_Forms_AttributeGetter = 1301,
+  kV8Document_Scripts_AttributeGetter = 1302,
+  kV8Document_Anchors_AttributeGetter = 1303,
+  kV8Document_Applets_AttributeGetter = 1304,
+  kXMLHttpRequestCrossOriginWithCredentials = 1305,
+  kMediaStreamTrackRemote = 1306,
+  kV8Node_IsConnected_AttributeGetter = 1307,
+  kShadowRootDelegatesFocus = 1308,
+  kMixedShadowRootV0AndV1 = 1309,
+  kImageDocumentInFrame = 1310,
+  kMediaDocument = 1311,
+  kMediaDocumentInFrame = 1312,
+  kPluginDocument = 1313,
+  kPluginDocumentInFrame = 1314,
+  kSinkDocument = 1315,
+  kSinkDocumentInFrame = 1316,
+  kTextDocument = 1317,
+  kTextDocumentInFrame = 1318,
+  kViewSourceDocument = 1319,
+  kFileAPINativeLineEndings = 1320,
+  kPointerEventAttributeCount = 1321,
+  kCompositedReplication = 1322,
+  kV8DataTransferItem_WebkitGetAsEntry_Method = 1325,
+  kV8HTMLInputElement_WebkitEntries_AttributeGetter = 1326,
+  kEntry_Filesystem_AttributeGetter_IsolatedFileSystem = 1327,
+  kEntry_GetMetadata_Method_IsolatedFileSystem = 1328,
+  kEntry_MoveTo_Method_IsolatedFileSystem = 1329,
+  kEntry_CopyTo_Method_IsolatedFileSystem = 1330,
+  kEntry_Remove_Method_IsolatedFileSystem = 1331,
+  kEntry_GetParent_Method_IsolatedFileSystem = 1332,
+  kEntry_ToURL_Method_IsolatedFileSystem = 1333,
+  kDuring_Microtask_Alert = 1334,
+  kDuring_Microtask_Confirm = 1335,
+  kDuring_Microtask_Print = 1336,
+  kDuring_Microtask_Prompt = 1337,
+  kDuring_Microtask_SyncXHR = 1338,
+  kCredentialManagerGetReturnedCredential = 1342,
+  kGeolocationInsecureOriginDeprecatedNotRemoved = 1343,
+  kGeolocationInsecureOriginIframeDeprecatedNotRemoved = 1344,
+  kProgressElementWithNoneAppearance = 1345,
+  kProgressElementWithProgressBarAppearance = 1346,
+  kPointerEventAddListenerCount = 1347,
+  kCSSValueAppearanceNone = 1351,
+  kCSSValueAppearanceNotNone = 1352,
+  kCSSValueAppearanceOthers = 1353,
+  kCSSValueAppearanceButton = 1354,
+  kCSSValueAppearanceCaret = 1355,
+  kCSSValueAppearanceCheckbox = 1356,
+  kCSSValueAppearanceMenulist = 1357,
+  kCSSValueAppearanceMenulistButton = 1358,
+  kCSSValueAppearanceListbox = 1359,
+  kCSSValueAppearanceRadio = 1360,
+  kCSSValueAppearanceSearchField = 1361,
+  kCSSValueAppearanceTextField = 1362,
+  kAudioContextCreatePannerAutomated = 1363,
+  kPannerNodeSetPosition = 1364,
+  kPannerNodeSetOrientation = 1365,
+  kAudioListenerSetPosition = 1366,
+  kAudioListenerSetOrientation = 1367,
+  kIntersectionObserver_Constructor = 1368,
+  kDurableStoragePersist = 1369,
+  kDurableStoragePersisted = 1370,
+  kDurableStorageEstimate = 1371,
+  kCSSDeepCombinatorAndShadow = 1375,
+  kOpacityWithPreserve3DQuirk = 1376,
+  kCSSSelectorPseudoReadOnly = 1377,
+  kCSSSelectorPseudoReadWrite = 1378,
+  // The above items are available in M52 branch
+
+  kCSSSelectorPseudoDefined = 1383,
+  kRTCPeerConnectionAddIceCandidatePromise = 1384,
+  kRTCPeerConnectionAddIceCandidateLegacy = 1385,
+  kRTCIceCandidateDefaultSdpMLineIndex = 1386,
+  kMediaStreamConstraintsOldAndNew = 1389,
+  kV8ArrayProtectorDirtied = 1390,
+  kV8ArraySpeciesModified = 1391,
+  kV8ArrayPrototypeConstructorModified = 1392,
+  kV8ArrayInstanceProtoModified = 1393,
+  kV8ArrayInstanceConstructorModified = 1394,
+  kV8LegacyFunctionDeclaration = 1395,
+  kV8RegExpPrototypeSourceGetter = 1396,
+  kV8RegExpPrototypeOldFlagGetter = 1397,
+  kV8DecimalWithLeadingZeroInStrictMode = 1398,
+  kGetUserMediaPrefixed = 1400,
+  kGetUserMediaLegacy = 1401,
+  kGetUserMediaPromise = 1402,
+  kCSSFilterFunctionNoArguments = 1403,
+  kV8LegacyDateParser = 1404,
+  kOpenSearchInsecureOriginInsecureTarget = 1405,
+  kOpenSearchInsecureOriginSecureTarget = 1406,
+  kOpenSearchSecureOriginInsecureTarget = 1407,
+  kOpenSearchSecureOriginSecureTarget = 1408,
+  kRegisterProtocolHandlerSecureOrigin = 1409,
+  kRegisterProtocolHandlerInsecureOrigin = 1410,
+  kCrossOriginWindowAlert = 1411,
+  kCrossOriginWindowConfirm = 1412,
+  kCrossOriginWindowPrompt = 1413,
+  kCrossOriginWindowPrint = 1414,
+  kMediaStreamOnActive = 1415,
+  kMediaStreamOnInactive = 1416,
+  kAddEventListenerPassiveTrue = 1417,
+  kAddEventListenerPassiveFalse = 1418,
+  kCSPReferrerDirective = 1419,
+  kDocumentOpen = 1420,
+  kElementRequestPointerLockInShadow = 1421,
+  kShadowRootPointerLockElement = 1422,
+  kDocumentPointerLockElementInV0Shadow = 1423,
+  kTextAreaMaxLength = 1424,
+  kTextAreaMinLength = 1425,
+  kTopNavigationFromSubFrame = 1426,
+  kPrefixedElementRequestFullscreenInShadow = 1427,
+  kMediaSourceAbortRemove = 1428,
+  kMediaSourceDurationTruncatingBuffered = 1429,
+  kAudioContextCrossOriginIframe = 1430,
+  // The above items are available in M53 branch
+
+  kPointerEventSetCapture = 1431,
+  kPointerEventDispatch = 1432,
+  kMIDIMessageEventReceivedTime = 1433,
+  kSummaryElementWithDisplayBlockAuthorRule = 1434,
+  kV8MediaStream_Active_AttributeGetter = 1435,
+  kBeforeInstallPromptEvent = 1436,
+  kBeforeInstallPromptEventUserChoice = 1437,
+  kBeforeInstallPromptEventPreventDefault = 1438,
+  kBeforeInstallPromptEventPrompt = 1439,
+  kExecCommandAltersHTMLStructure = 1440,
+  kSecureContextCheckPassed = 1441,
+  kSecureContextCheckFailed = 1442,
+  kSecureContextCheckForSandboxedOriginPassed = 1443,
+  kSecureContextCheckForSandboxedOriginFailed = 1444,
+  kV8DefineGetterOrSetterWouldThrow = 1445,
+  kV8FunctionConstructorReturnedUndefined = 1446,
+  kV8BroadcastChannel_Constructor = 1447,
+  kV8BroadcastChannel_PostMessage_Method = 1448,
+  kV8BroadcastChannel_Close_Method = 1449,
+  kTouchStartFired = 1450,
+  kMouseDownFired = 1451,
+  kPointerDownFired = 1452,
+  kPointerDownFiredForTouch = 1453,
+  kPointerEventDispatchPointerDown = 1454,
+  kSVGSMILBeginOrEndEventValue = 1455,
+  kSVGSMILBeginOrEndSyncbaseValue = 1456,
+  kSVGSMILElementInsertedAfterLoad = 1457,
+  kV8VisualViewport_OffsetLeft_AttributeGetter = 1458,
+  kV8VisualViewport_OffsetTop_AttributeGetter = 1459,
+  kV8VisualViewport_PageLeft_AttributeGetter = 1460,
+  kV8VisualViewport_PageTop_AttributeGetter = 1461,
+  kV8VisualViewport_Width_AttributeGetter = 1462,
+  kV8VisualViewport_Height_AttributeGetter = 1463,
+  kV8VisualViewport_Scale_AttributeGetter = 1464,
+  kVisualViewportScrollFired = 1465,
+  kVisualViewportResizeFired = 1466,
+  kNodeGetRootNode = 1467,
+  kSlotChangeEventAddListener = 1468,
+  kCSSValueAppearanceButtonRendered = 1469,
+  kCSSValueAppearanceButtonForAnchor = 1470,
+  kCSSValueAppearanceButtonForButton = 1471,
+  kCSSValueAppearanceButtonForOtherButtons = 1472,
+  kCSSValueAppearanceTextFieldRendered = 1473,
+  kCSSValueAppearanceTextFieldForSearch = 1474,
+  kCSSValueAppearanceTextFieldForTextField = 1475,
+  kRTCPeerConnectionGetStats = 1476,
+  kSVGSMILAnimationAppliedEffect = 1477,
+  kPerformanceResourceTimingSizes = 1478,
+  kEventSourceDocument = 1479,
+  kEventSourceWorker = 1480,
+  kSingleOriginInTimingAllowOrigin = 1481,
+  kMultipleOriginsInTimingAllowOrigin = 1482,
+  kStarInTimingAllowOrigin = 1483,
+  kSVGSMILAdditiveAnimation = 1484,
+  kSendBeaconWithNonSimpleContentType = 1485,
+  kChromeLoadTimesRequestTime = 1486,
+  kChromeLoadTimesStartLoadTime = 1487,
+  kChromeLoadTimesCommitLoadTime = 1488,
+  kChromeLoadTimesFinishDocumentLoadTime = 1489,
+  kChromeLoadTimesFinishLoadTime = 1490,
+  kChromeLoadTimesFirstPaintTime = 1491,
+  kChromeLoadTimesFirstPaintAfterLoadTime = 1492,
+  kChromeLoadTimesNavigationType = 1493,
+  kChromeLoadTimesWasFetchedViaSpdy = 1494,
+  kChromeLoadTimesWasNpnNegotiated = 1495,
+  kChromeLoadTimesNpnNegotiatedProtocol = 1496,
+  kChromeLoadTimesWasAlternateProtocolAvailable = 1497,
+  kChromeLoadTimesConnectionInfo = 1498,
+  kChromeLoadTimesUnknown = 1499,
+  kSVGViewElement = 1500,
+  kWebShareShare = 1501,
+  kAuxclickAddListenerCount = 1502,
+  kHTMLCanvasElement = 1503,
+  kSVGSMILAnimationElementTiming = 1504,
+  kSVGSMILBeginEndAnimationElement = 1505,
+  kSVGSMILPausing = 1506,
+  kSVGSMILCurrentTime = 1507,
+  kHTMLBodyElementOnSelectionChangeAttribute = 1508,
+  kForeignFetchInterception = 1509,
+  kUsbGetDevices = 1519,
+  kUsbRequestDevice = 1520,
+  kUsbDeviceOpen = 1521,
+  kUsbDeviceClose = 1522,
+  kUsbDeviceSelectConfiguration = 1523,
+  kUsbDeviceClaimInterface = 1524,
+  kUsbDeviceReleaseInterface = 1525,
+  kUsbDeviceSelectAlternateInterface = 1526,
+  kUsbDeviceControlTransferIn = 1527,
+  kUsbDeviceControlTransferOut = 1528,
+  kUsbDeviceClearHalt = 1529,
+  kUsbDeviceTransferIn = 1530,
+  kUsbDeviceTransferOut = 1531,
+  kUsbDeviceIsochronousTransferIn = 1532,
+  kUsbDeviceIsochronousTransferOut = 1533,
+  kUsbDeviceReset = 1534,
+  // The above items are available in M54 branch
+
+  kPointerEnterLeaveFired = 1535,
+  kPointerOverOutFired = 1536,
+  kDraggableAttribute = 1539,
+  kCleanScriptElementWithNonce = 1540,
+  kPotentiallyInjectedScriptElementWithNonce = 1541,
+  kPendingStylesheetAddedAfterBodyStarted = 1542,
+  kUntrustedMouseDownEventDispatchedToSelect = 1543,
+  kBlockedSniffingAudioToScript = 1544,
+  kBlockedSniffingVideoToScript = 1545,
+  kBlockedSniffingCSVToScript = 1546,
+  kMetaSetCookie = 1547,
+  kMetaRefresh = 1548,
+  kMetaSetCookieWhenCSPBlocksInlineScript = 1549,
+  kMetaRefreshWhenCSPBlocksInlineScript = 1550,
+  kMiddleClickAutoscrollStart = 1551,
+  kRTCPeerConnectionCreateOfferOptionsOfferToReceive = 1553,
+  kDragAndDropScrollStart = 1554,
+  kPresentationConnectionListConnectionAvailableEventListener = 1555,
+  kWebAudioAutoplayCrossOriginIframe = 1556,
+  kVRGetDisplays = 1558,
+  kXSSAuditorBlockedScript = 1581,
+  kXSSAuditorBlockedEntirePage = 1582,
+  kXSSAuditorDisabled = 1583,
+  kXSSAuditorEnabledFilter = 1584,
+  kXSSAuditorEnabledBlock = 1585,
+  kXSSAuditorInvalid = 1586,
+  kTextInputEventOnInput = 1589,
+  kTextInputEventOnTextArea = 1590,
+  kTextInputEventOnContentEditable = 1591,
+  kTextInputEventOnNotNode = 1592,
+  kWebkitBeforeTextInsertedOnInput = 1593,
+  kWebkitBeforeTextInsertedOnTextArea = 1594,
+  kWebkitBeforeTextInsertedOnContentEditable = 1595,
+  kWebkitBeforeTextInsertedOnNotNode = 1596,
+  kWebkitEditableContentChangedOnInput = 1597,
+  kWebkitEditableContentChangedOnTextArea = 1598,
+  kWebkitEditableContentChangedOnContentEditable = 1599,
+  kWebkitEditableContentChangedOnNotNode = 1600,
+  kV8NavigatorUserMediaError_ConstraintName_AttributeGetter = 1601,
+  kV8HTMLMediaElement_SrcObject_AttributeGetter = 1602,
+  kV8HTMLMediaElement_SrcObject_AttributeSetter = 1603,
+  kCreateObjectURLBlob = 1604,
+  kCreateObjectURLMediaSource = 1605,
+  kCreateObjectURLMediaStream = 1606,
+  kDocumentCreateTouchWindowNull = 1607,
+  kDocumentCreateTouchWindowWrongType = 1608,
+  kDocumentCreateTouchTargetNull = 1609,
+  kDocumentCreateTouchTargetWrongType = 1610,
+  kDocumentCreateTouchMoreThanSevenArguments = 1612,
+  kLongTaskObserver = 1615,
+  kCSSOffsetInEffect = 1617,
+  // The above items are available in M55 branch
+
+  kVRGetDisplaysInsecureOrigin = 1618,
+  kVRRequestPresent = 1619,
+  kVRRequestPresentInsecureOrigin = 1620,
+  kVRDeprecatedFieldOfView = 1621,
+  kVideoInCanvas = 1622,
+  kHiddenAutoplayedVideoInCanvas = 1623,
+  kOffscreenCanvas = 1624,
+  kGamepadPose = 1625,
+  kGamepadHand = 1626,
+  kGamepadDisplayId = 1627,
+  kGamepadButtonTouched = 1628,
+  kGamepadPoseHasOrientation = 1629,
+  kGamepadPoseHasPosition = 1630,
+  kGamepadPosePosition = 1631,
+  kGamepadPoseLinearVelocity = 1632,
+  kGamepadPoseLinearAcceleration = 1633,
+  kGamepadPoseOrientation = 1634,
+  kGamepadPoseAngularVelocity = 1635,
+  kGamepadPoseAngularAcceleration = 1636,
+  kV8RTCDataChannel_MaxRetransmitTime_AttributeGetter = 1638,
+  kV8RTCDataChannel_MaxRetransmits_AttributeGetter = 1639,
+  kV8RTCDataChannel_Reliable_AttributeGetter = 1640,
+  kV8RTCPeerConnection_AddStream_Method = 1641,
+  kV8RTCPeerConnection_CreateDTMFSender_Method = 1642,
+  kV8RTCPeerConnection_GetLocalStreams_Method = 1643,
+  kV8RTCPeerConnection_GetRemoteStreams_Method = 1644,
+  kV8RTCPeerConnection_GetStreamById_Method = 1645,
+  kV8RTCPeerConnection_RemoveStream_Method = 1646,
+  kRTCPeerConnectionCreateDataChannelMaxRetransmitTime = 1648,
+  kRTCPeerConnectionCreateDataChannelMaxRetransmits = 1649,
+  kAudioContextCreateConstantSource = 1650,
+  kWebAudioConstantSourceNode = 1651,
+  kLoopbackEmbeddedInSecureContext = 1652,
+  kLoopbackEmbeddedInNonSecureContext = 1653,
+  kBlinkMacSystemFont = 1654,
+  kRTCIceServerURL = 1656,
+  kRTCIceServerURLs = 1657,
+  kOffscreenCanvasTransferToImageBitmap2D = 1658,
+  kOffscreenCanvasTransferToImageBitmapWebGL = 1659,
+  kOffscreenCanvasCommit2D = 1660,
+  kOffscreenCanvasCommitWebGL = 1661,
+  kRTCConfigurationIceTransportPolicy = 1662,
+  kRTCConfigurationIceTransports = 1664,
+  kDocumentFullscreenElementInV0Shadow = 1665,
+  kScriptWithCSPBypassingSchemeParserInserted = 1666,
+  kScriptWithCSPBypassingSchemeNotParserInserted = 1667,
+  kDocumentCreateElement2ndArgStringHandling = 1668,
+  kV8MediaRecorder_Start_Method = 1669,
+  kWebBluetoothRequestDevice = 1670,
+  kUnitlessPerspectiveInPerspectiveProperty = 1671,
+  kUnitlessPerspectiveInTransformProperty = 1672,
+  kV8RTCSessionDescription_Type_AttributeGetter = 1673,
+  kV8RTCSessionDescription_Type_AttributeSetter = 1674,
+  kV8RTCSessionDescription_Sdp_AttributeGetter = 1675,
+  kV8RTCSessionDescription_Sdp_AttributeSetter = 1676,
+  kRTCSessionDescriptionInitNoType = 1677,
+  kRTCSessionDescriptionInitNoSdp = 1678,
+  kHTMLMediaElementPreloadForcedMetadata = 1679,
+  kGenericSensorStart = 1680,
+  kGenericSensorStop = 1681,
+  kTouchEventPreventedNoTouchAction = 1682,
+  kTouchEventPreventedForcedDocumentPassiveNoTouchAction = 1683,
+  kV8Event_StopPropagation_Method = 1684,
+  kV8Event_StopImmediatePropagation_Method = 1685,
+  kImageCaptureConstructor = 1686,
+  kV8Document_RootScroller_AttributeGetter = 1687,
+  kV8Document_RootScroller_AttributeSetter = 1688,
+  kCustomElementRegistryDefine = 1689,
+  kLinkHeaderServiceWorker = 1690,
+  kCSSShadowPiercingDescendantCombinator = 1691,
+  // The above items are available in M56 branch.
+
+  kCSSFlexibleBox = 1692,
+  kCSSGridLayout = 1693,
+  kFullscreenAllowedByOrientationChange = 1696,
+  kServiceWorkerRespondToNavigationRequestWithRedirectedResponse = 1697,
+  kV8AudioContext_Constructor = 1698,
+  kV8OfflineAudioContext_Constructor = 1699,
+  kAppInstalledEventAddListener = 1700,
+  kAudioContextGetOutputTimestamp = 1701,
+  kV8MediaStreamAudioDestinationNode_Constructor = 1702,
+  kV8AnalyserNode_Constructor = 1703,
+  kV8AudioBuffer_Constructor = 1704,
+  kV8AudioBufferSourceNode_Constructor = 1705,
+  kV8AudioProcessingEvent_Constructor = 1706,
+  kV8BiquadFilterNode_Constructor = 1707,
+  kV8ChannelMergerNode_Constructor = 1708,
+  kV8ChannelSplitterNode_Constructor = 1709,
+  kV8ConstantSourceNode_Constructor = 1710,
+  kV8ConvolverNode_Constructor = 1711,
+  kV8DelayNode_Constructor = 1712,
+  kV8DynamicsCompressorNode_Constructor = 1713,
+  kV8GainNode_Constructor = 1714,
+  kV8IIRFilterNode_Constructor = 1715,
+  kV8MediaElementAudioSourceNode_Constructor = 1716,
+  kV8MediaStreamAudioSourceNode_Constructor = 1717,
+  kV8OfflineAudioCompletionEvent_Constructor = 1718,
+  kV8OscillatorNode_Constructor = 1719,
+  kV8PannerNode_Constructor = 1720,
+  kV8PeriodicWave_Constructor = 1721,
+  kV8StereoPannerNode_Constructor = 1722,
+  kV8WaveShaperNode_Constructor = 1723,
+  kV8Headers_GetAll_Method = 1724,
+  kNavigatorVibrateEngagementNone = 1725,
+  kNavigatorVibrateEngagementMinimal = 1726,
+  kNavigatorVibrateEngagementLow = 1727,
+  kNavigatorVibrateEngagementMedium = 1728,
+  kNavigatorVibrateEngagementHigh = 1729,
+  kNavigatorVibrateEngagementMax = 1730,
+  kAlertEngagementNone = 1731,
+  kAlertEngagementMinimal = 1732,
+  kAlertEngagementLow = 1733,
+  kAlertEngagementMedium = 1734,
+  kAlertEngagementHigh = 1735,
+  kAlertEngagementMax = 1736,
+  kConfirmEngagementNone = 1737,
+  kConfirmEngagementMinimal = 1738,
+  kConfirmEngagementLow = 1739,
+  kConfirmEngagementMedium = 1740,
+  kConfirmEngagementHigh = 1741,
+  kConfirmEngagementMax = 1742,
+  kPromptEngagementNone = 1743,
+  kPromptEngagementMinimal = 1744,
+  kPromptEngagementLow = 1745,
+  kPromptEngagementMedium = 1746,
+  kPromptEngagementHigh = 1747,
+  kPromptEngagementMax = 1748,
+  kTopNavInSandbox = 1749,
+  kTopNavInSandboxWithoutGesture = 1750,
+  kTopNavInSandboxWithPerm = 1751,
+  kTopNavInSandboxWithPermButNoGesture = 1752,
+  kReferrerPolicyHeader = 1753,
+  kHTMLAnchorElementReferrerPolicyAttribute = 1754,
+  kHTMLIFrameElementReferrerPolicyAttribute = 1755,
+  kHTMLImageElementReferrerPolicyAttribute = 1756,
+  kHTMLLinkElementReferrerPolicyAttribute = 1757,
+  kBaseElement = 1758,
+  kBaseWithCrossOriginHref = 1759,
+  kBaseWithDataHref = 1760,
+  kBaseWithNewlinesInTarget = 1761,
+  kBaseWithOpenBracketInTarget = 1762,
+  kBaseWouldBeBlockedByDefaultSrc = 1763,
+  kV8AssigmentExpressionLHSIsCallInSloppy = 1764,
+  kV8AssigmentExpressionLHSIsCallInStrict = 1765,
+  kV8PromiseConstructorReturnedUndefined = 1766,
+  kFormSubmittedWithUnclosedFormControl = 1767,
+  kScrollbarUseVerticalScrollbarButton = 1777,
+  kScrollbarUseVerticalScrollbarThumb = 1778,
+  kScrollbarUseVerticalScrollbarTrack = 1779,
+  kScrollbarUseHorizontalScrollbarButton = 1780,
+  kScrollbarUseHorizontalScrollbarThumb = 1781,
+  kScrollbarUseHorizontalScrollbarTrack = 1782,
+  kHTMLTableCellElementColspan = 1783,
+  kHTMLTableCellElementColspanGreaterThan1000 = 1784,
+  kHTMLTableCellElementColspanGreaterThan8190 = 1785,
+  kSelectionAddRangeIntersect = 1786,
+  kPostMessageFromInsecureToSecureToplevel = 1787,
+  // The above items are available in M57 branch.
+
+  kV8MediaSession_Metadata_AttributeGetter = 1788,
+  kV8MediaSession_Metadata_AttributeSetter = 1789,
+  kV8MediaSession_PlaybackState_AttributeGetter = 1790,
+  kV8MediaSession_PlaybackState_AttributeSetter = 1791,
+  kV8MediaSession_SetActionHandler_Method = 1792,
+  kWebNFCPush = 1793,
+  kWebNFCCancelPush = 1794,
+  kWebNFCWatch = 1795,
+  kWebNFCCancelWatch = 1796,
+  kAudioParamCancelAndHoldAtTime = 1797,
+  kCSSValueUserModifyReadOnly = 1798,
+  kCSSValueUserModifyReadWrite = 1799,
+  kCSSValueUserModifyReadWritePlaintextOnly = 1800,
+  kCSSValueOnDemand = 1802,
+  kServiceWorkerNavigationPreload = 1803,
+  kFullscreenRequestWithPendingElement = 1804,
+  kHTMLIFrameElementAllowfullscreenAttributeSetAfterContentLoad = 1805,
+  kPointerEventSetCaptureOutsideDispatch = 1806,
+  kNotificationPermissionRequestedInsecureOrigin = 1807,
+  kV8DeprecatedStorageInfo_QueryUsageAndQuota_Method = 1808,
+  kV8DeprecatedStorageInfo_RequestQuota_Method = 1809,
+  kV8DeprecatedStorageQuota_QueryUsageAndQuota_Method = 1810,
+  kV8DeprecatedStorageQuota_RequestQuota_Method = 1811,
+  kV8FileReaderSync_Constructor = 1812,
+  kUncancelableTouchEventPreventDefaulted = 1813,
+  kUncancelableTouchEventDueToMainThreadResponsivenessPreventDefaulted = 1814,
+  kV8HTMLVideoElement_Poster_AttributeGetter = 1815,
+  kV8HTMLVideoElement_Poster_AttributeSetter = 1816,
+  kNotificationPermissionRequestedIframe = 1817,
+  kPresentationReceiverInsecureOrigin = 1819,
+  kPresentationReceiverSecureOrigin = 1820,
+  kPresentationRequestInsecureOrigin = 1821,
+  kPresentationRequestSecureOrigin = 1822,
+  kRtcpMuxPolicyNegotiate = 1823,
+  kDOMClobberedVariableAccessed = 1824,
+  kHTMLDocumentCreateProcessingInstruction = 1825,
+  kFetchResponseConstructionWithStream = 1826,
+  kLocationOrigin = 1827,
+  kDocumentOrigin = 1828,
+  kCanvas2DFilter = 1830,
+  kCanvas2DImageSmoothingQuality = 1831,
+  kCanvasToBlob = 1832,
+  kCanvasToDataURL = 1833,
+  kOffscreenCanvasConvertToBlob = 1834,
+  kSVGInCanvas2D = 1835,
+  kSVGInWebGL = 1836,
+  kSelectionFuncionsChangeFocus = 1837,
+  kHTMLObjectElementGetter = 1838,
+  kHTMLObjectElementSetter = 1839,
+  kHTMLEmbedElementGetter = 1840,
+  kHTMLEmbedElementSetter = 1841,
+  kTransformUsesBoxSizeOnSVG = 1842,
+  // The above items are available in M58 branch.
+
+  kScrollByKeyboardArrowKeys = 1843,
+  kScrollByKeyboardPageUpDownKeys = 1844,
+  kScrollByKeyboardHomeEndKeys = 1845,
+  kScrollByKeyboardSpacebarKey = 1846,
+  kScrollByTouch = 1847,
+  kScrollByWheel = 1848,
+  kScheduledActionIgnored = 1849,
+  kGetCanvas2DContextAttributes = 1850,
+  kV8HTMLInputElement_Capture_AttributeGetter = 1851,
+  kV8HTMLInputElement_Capture_AttributeSetter = 1852,
+  kHTMLMediaElementControlsListAttribute = 1853,
+  kHTMLMediaElementControlsListNoDownload = 1854,
+  kHTMLMediaElementControlsListNoFullscreen = 1855,
+  kHTMLMediaElementControlsListNoRemotePlayback = 1856,
+  kPointerEventClickRetargetCausedByCapture = 1857,
+  kVRDisplayDisplayName = 1861,
+  kVREyeParametersOffset = 1862,
+  kVRPoseLinearVelocity = 1863,
+  kVRPoseLinearAcceleration = 1864,
+  kVRPoseAngularVelocity = 1865,
+  kVRPoseAngularAcceleration = 1866,
+  kCSSOverflowPaged = 1867,
+  kChildSrcAllowedWorkerThatScriptSrcBlocked = 1868,
+  kHTMLTableElementPresentationAttributeBackground = 1869,
+  kV8Navigator_GetInstalledRelatedApps_Method = 1870,
+  kNamedAccessOnWindow_ChildBrowsingContext = 1871,
+  kNamedAccessOnWindow_ChildBrowsingContext_CrossOriginNameMismatch = 1872,
+  kV0CustomElementsRegisterHTMLCustomTag = 1873,
+  kV0CustomElementsRegisterHTMLTypeExtension = 1874,
+  kV0CustomElementsRegisterSVGElement = 1875,
+  kV0CustomElementsRegisterEmbedderElement = 1876,
+  kV0CustomElementsCreateCustomTagElement = 1877,
+  kV0CustomElementsCreateTypeExtensionElement = 1878,
+  kV0CustomElementsConstruct = 1879,
+  kV8IDBObserver_Observe_Method = 1880,
+  kV8IDBObserver_Unobserve_Method = 1881,
+  kWebBluetoothRemoteCharacteristicGetDescriptor = 1882,
+  kWebBluetoothRemoteCharacteristicGetDescriptors = 1883,
+  kWebBluetoothRemoteCharacteristicReadValue = 1884,
+  kWebBluetoothRemoteCharacteristicWriteValue = 1885,
+  kWebBluetoothRemoteCharacteristicStartNotifications = 1886,
+  kWebBluetoothRemoteCharacteristicStopNotifications = 1887,
+  kWebBluetoothRemoteDescriptorReadValue = 1888,
+  kWebBluetoothRemoteDescriptorWriteValue = 1889,
+  kWebBluetoothRemoteServerConnect = 1890,
+  kWebBluetoothRemoteServerDisconnect = 1891,
+  kWebBluetoothRemoteServerGetPrimaryService = 1892,
+  kWebBluetoothRemoteServerGetPrimaryServices = 1893,
+  kWebBluetoothRemoteServiceGetCharacteristic = 1894,
+  kWebBluetoothRemoteServiceGetCharacteristics = 1895,
+  kHTMLContentElement = 1896,
+  kHTMLShadowElement = 1897,
+  kHTMLSlotElement = 1898,
+  kAccelerometerConstructor = 1899,
+  kAbsoluteOrientationSensorConstructor = 1900,
+  kAmbientLightSensorConstructor = 1901,
+  kGenericSensorOnActivate = 1902,
+  kGenericSensorOnChange = 1903,
+  kGenericSensorOnError = 1904,
+  kGenericSensorActivated = 1905,
+  kGyroscopeConstructor = 1906,
+  kMagnetometerConstructor = 1907,
+  kOrientationSensorPopulateMatrix = 1908,
+  kWindowOpenWithInvalidURL = 1909,
+  kCrossOriginMainFrameNulledNameAccessed = 1910,
+  kMenuItemElementIconAttribute = 1911,
+  kWebkitCSSMatrixSetMatrixValue = 1912,
+  kWebkitCSSMatrixConstructFromString = 1913,
+  kCanRequestURLHTTPContainingNewline = 1914,
+  kGetGamepads = 1916,
+  kV8SVGPathElement_GetPathSegAtLength_Method = 1917,
+  kMediaStreamConstraintsAudio = 1918,
+  kMediaStreamConstraintsAudioUnconstrained = 1919,
+  kMediaStreamConstraintsVideo = 1920,
+  kMediaStreamConstraintsVideoUnconstrained = 1921,
+  kMediaStreamConstraintsWidth = 1922,
+  kMediaStreamConstraintsHeight = 1923,
+  kMediaStreamConstraintsAspectRatio = 1924,
+  kMediaStreamConstraintsFrameRate = 1925,
+  kMediaStreamConstraintsFacingMode = 1926,
+  kMediaStreamConstraintsVolume = 1927,
+  kMediaStreamConstraintsSampleRate = 1928,
+  kMediaStreamConstraintsSampleSize = 1929,
+  kMediaStreamConstraintsEchoCancellation = 1930,
+  kMediaStreamConstraintsLatency = 1931,
+  kMediaStreamConstraintsChannelCount = 1932,
+  kMediaStreamConstraintsDeviceIdAudio = 1933,
+  kMediaStreamConstraintsDeviceIdVideo = 1934,
+  kMediaStreamConstraintsDisableLocalEcho = 1935,
+  kMediaStreamConstraintsGroupIdAudio = 1936,
+  kMediaStreamConstraintsGroupIdVideo = 1937,
+  kMediaStreamConstraintsVideoKind = 1938,
+  kMediaStreamConstraintsDepthNear = 1939,
+  kMediaStreamConstraintsDepthFar = 1940,
+  kMediaStreamConstraintsFocalLengthX = 1941,
+  kMediaStreamConstraintsFocalLengthY = 1942,
+  kMediaStreamConstraintsMediaStreamSourceAudio = 1943,
+  kMediaStreamConstraintsMediaStreamSourceVideo = 1944,
+  kMediaStreamConstraintsRenderToAssociatedSink = 1945,
+  kMediaStreamConstraintsHotwordEnabled = 1946,
+  kMediaStreamConstraintsGoogEchoCancellation = 1947,
+  kMediaStreamConstraintsGoogExperimentalEchoCancellation = 1948,
+  kMediaStreamConstraintsGoogAutoGainControl = 1949,
+  kMediaStreamConstraintsGoogExperimentalAutoGainControl = 1950,
+  kMediaStreamConstraintsGoogNoiseSuppression = 1951,
+  kMediaStreamConstraintsGoogHighpassFilter = 1952,
+  kMediaStreamConstraintsGoogTypingNoiseDetection = 1953,
+  kMediaStreamConstraintsGoogExperimentalNoiseSuppression = 1954,
+  kMediaStreamConstraintsGoogBeamforming = 1955,
+  kMediaStreamConstraintsGoogArrayGeometry = 1956,
+  kMediaStreamConstraintsGoogAudioMirroring = 1957,
+  kMediaStreamConstraintsGoogDAEchoCancellation = 1958,
+  kMediaStreamConstraintsGoogNoiseReduction = 1959,
+  kMediaStreamConstraintsGoogPowerLineFrequency = 1960,
+  // The above items are available in M59 branch.
+
+  kViewportFixedPositionUnderFilter = 1961,
+  kRequestMIDIAccessWithSysExOption = 1962,
+  kRequestMIDIAccessIframeWithSysExOption = 1963,
+  kGamepadAxes = 1964,
+  kGamepadButtons = 1965,
+  kVibrateWithoutUserGesture = 1966,
+  kDispatchMouseEventOnDisabledFormControl = 1967,
+  kElementNameDOMInvalidHTMLParserValid = 1968,
+  kElementNameDOMValidHTMLParserInvalid = 1969,
+  kGATTServerDisconnectedEvent = 1970,
+  kAnchorClickDispatchForNonConnectedNode = 1971,
+  kHTMLParseErrorNestedForm = 1972,
+  kFontShapingNotDefGlyphObserved = 1973,
+  kPostMessageOutgoingWouldBeBlockedByConnectSrc = 1974,
+  kPostMessageIncomingWouldBeBlockedByConnectSrc = 1975,
+  kPaymentRequestNetworkNameInSupportedMethods = 1976,
+  kCrossOriginPropertyAccess = 1977,
+  kCrossOriginPropertyAccessFromOpener = 1978,
+  kCredentialManagerCreate = 1979,
+  kWebDatabaseCreateDropFTS3Table = 1980,
+  kFieldEditInSecureContext = 1981,
+  kFieldEditInNonSecureContext = 1982,
+  kCredentialManagerCredentialRequestOptionsUnmediated = 1983,
+  kCredentialManagerGetMediationRequired = 1984,
+  kCredentialManagerIdName = 1985,
+  kCredentialManagerPasswordName = 1986,
+  kCredentialManagerAdditionalData = 1987,
+  kCredentialManagerCustomFetch = 1988,
+  kNetInfoRtt = 1989,
+  kNetInfoDownlink = 1990,
+  kShapeDetection_BarcodeDetectorConstructor = 1991,
+  kShapeDetection_FaceDetectorConstructor = 1992,
+  kShapeDetection_TextDetectorConstructor = 1993,
+  kCredentialManagerCredentialRequestOptionsOnlyUnmediated = 1994,
+  kInertAttribute = 1995,
+  kPluginInstanceAccessFromIsolatedWorld = 1996,
+  kPluginInstanceAccessFromMainWorld = 1997,
+  kRequestFullscreenForDialogElement = 1998,
+  kRequestFullscreenForDialogElementInTopLayer = 1999,
+  kShowModalForElementInFullscreenStack = 2000,
+  kThreeValuedPositionBackground = 2001,
+  kThreeValuedPositionBasicShape = 2002,
+  kThreeValuedPositionGradient = 2003,
+  kThreeValuedPositionObjectPosition = 2004,
+  kThreeValuedPositionPerspectiveOrigin = 2005,
+  kUnitlessZeroAngleFilter = 2007,
+  kUnitlessZeroAngleGradient = 2008,
+  kUnitlessZeroAngleTransform = 2010,
+  kHTMLOListElementStartGetterReversedWithoutStartAttribute = 2011,
+  kCredentialManagerPreventSilentAccess = 2012,
+  kNetInfoEffectiveType = 2013,
+  kV8SpeechRecognition_Start_Method = 2014,
+  kTableRowDirectionDifferentFromTable = 2015,
+  kTableSectionDirectionDifferentFromTable = 2016,
+  // The above items are available in M60 branch.
+
+  kClientHintsDeviceRAM = 2017,
+  kCSSRegisterProperty = 2018,
+  kRelativeOrientationSensorConstructor = 2019,
+  kSmoothScrollJSInterventionActivated = 2020,
+  kBudgetAPIGetCost = 2021,
+  kBudgetAPIGetBudget = 2022,
+  kCrossOriginMainFrameNulledNonEmptyNameAccessed = 2023,
+
+  // Add new features immediately above this line. Don't change assigned
+  // numbers of any item, and don't reuse removed slots.
+  // Also, run update_use_counter_feature_enum.py in
+  // chromium/src/tools/metrics/histograms/ to update the UMA mapping.
+  kNumberOfFeatures,  // This enum value must be last.
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/public/web/WebPluginContainer.h b/third_party/WebKit/public/web/WebPluginContainer.h
index 9d2323a..977bbb5cb 100644
--- a/third_party/WebKit/public/web/WebPluginContainer.h
+++ b/third_party/WebKit/public/web/WebPluginContainer.h
@@ -53,6 +53,7 @@
   enum TouchEventRequestType {
     kTouchEventRequestTypeNone,
     kTouchEventRequestTypeRaw,
+    kTouchEventRequestTypeRawLowLatency,
     kTouchEventRequestTypeSynthesizedMouse,
   };
 
diff --git a/third_party/WebKit/public/web/WebWidgetClient.h b/third_party/WebKit/public/web/WebWidgetClient.h
index cd62e3384..c948511 100644
--- a/third_party/WebKit/public/web/WebWidgetClient.h
+++ b/third_party/WebKit/public/web/WebWidgetClient.h
@@ -137,6 +137,9 @@
   // Called to update if touch events should be sent.
   virtual void HasTouchEventHandlers(bool) {}
 
+  // Called to update whether low latency input mode is enabled or not.
+  virtual void SetNeedsLowLatencyInput(bool) {}
+
   // Called during WebWidget::HandleInputEvent for a TouchStart event to inform
   // the embedder of the touch actions that are permitted for this touch.
   virtual void SetTouchAction(WebTouchAction touch_action) {}
diff --git a/third_party/polymer/v1_0/extract_inline_scripts.py b/third_party/polymer/v1_0/extract_inline_scripts.py
new file mode 100644
index 0000000..901394d9
--- /dev/null
+++ b/third_party/polymer/v1_0/extract_inline_scripts.py
@@ -0,0 +1,39 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Extracts inlined scripts from the provided Polymer HTM files to a separate JS
+file. A JS file extracted from the file with name 'foo.html' will have a name
+'foo-extracted.js'. Inclusion of the script file will be added to
+'foo.html' as '<script src="foo-extracted.js"></script>'.
+"""
+
+from os import path as os_path
+import sys
+import shutil
+
+_HERE_PATH = os_path.dirname(__file__)
+_SRC_PATH = os_path.normpath(os_path.join(_HERE_PATH, '..', '..', '..'))
+sys.path.append(os_path.join(_SRC_PATH, 'third_party', 'node'))
+import node
+import node_modules
+
+
+def main(original_html):
+  name = os_path.splitext(os_path.basename(original_html))[0]
+  dst_dir = os_path.dirname(original_html)
+  extracted_html = os_path.join(dst_dir, name + '-extracted.html')
+  extracted_js = os_path.join(dst_dir, name + '-extracted.js')
+
+  node.RunNode([
+      node_modules.PathToCrisper(),
+      '--script-in-head', 'false',
+      '--source', original_html,
+      '--html', extracted_html,
+      '--js', extracted_js])
+
+  shutil.move(extracted_html, original_html)
+
+
+if __name__ == '__main__':
+  main(sys.argv[1])
diff --git a/third_party/polymer/v1_0/extract_inline_scripts.sh b/third_party/polymer/v1_0/extract_inline_scripts.sh
deleted file mode 100755
index ca60af2..0000000
--- a/third_party/polymer/v1_0/extract_inline_scripts.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-set -e
-
-if [ "$#" -ne 2 ]
-then
-  echo "Usage: $0 <src_dir> <dst_dir>"
-  echo
-  echo "Extracts inlined scripts from <src_dir> to <dst_dir>" \
-       "Polymer HTML files found in the destination directory to separate JS" \
-       "files. A JS file extracted from the file with name 'foo.html' will" \
-       "have a name 'foo-extracted.js'. Inclusion of the script file will be" \
-       "added to 'foo.html': '<script src=\"foo-extracted.js\"></script>'."
-  exit 1
-fi
-
-src="${1%/}"
-dst="${2%/}"
-
-rsync -c --delete -r -v --exclude-from="rsync_exclude.txt" \
-    --prune-empty-dirs "$src/" "$dst/"
-
-find "$dst" -name "*.html" | \
-xargs grep -l "<script>" | \
-while read original_html_name
-do
-  dir=$(dirname "$original_html_name")
-  name=$(basename "$original_html_name" .html)
-
-  html_without_js="$dir/$name-extracted.html"
-  extracted_js="$dir/$name-extracted.js"
-  echo "Crisping $original_html_name"
-  crisper --script-in-head=false --source "$original_html_name" \
-      --html "$html_without_js" --js "$extracted_js"
-  mv "$html_without_js" "$original_html_name"
-done
diff --git a/third_party/polymer/v1_0/reproduce.sh b/third_party/polymer/v1_0/reproduce.sh
index 821a645..51aa656 100755
--- a/third_party/polymer/v1_0/reproduce.sh
+++ b/third_party/polymer/v1_0/reproduce.sh
@@ -20,7 +20,6 @@
 
 check_dep "which npm" "npm" "visiting https://nodejs.org/en/"
 check_dep "which bower" "bower" "npm install -g bower"
-check_dep "which crisper" "crisper" "npm install -g crisper"
 check_dep "which rsync" "rsync" "apt-get install rsync"
 check_dep "python -c 'import bs4'" "bs4" "apt-get install python-bs4"
 check_dep "sed --version | grep GNU" \
@@ -70,7 +69,16 @@
 NBSP=$(python -c 'print u"\u00A0".encode("utf-8")')
 sed -i 's/['"$NBSP"']/\\u00A0/g' components/polymer/polymer-mini.html
 
-./extract_inline_scripts.sh components components-chromium
+rsync -c --delete -r -v --exclude-from="rsync_exclude.txt" \
+    --prune-empty-dirs "components/" "components-chromium/"
+
+find "components-chromium/" -name "*.html" | \
+xargs grep -l "<script>" | \
+while read original_html_name
+do
+  echo "Crisping $original_html_name"
+  python extract_inline_scripts.py $original_html_name
+done
 
 # Remove import of external resource in font-roboto (fonts.googleapis.com)
 # and apply additional chrome specific patches. NOTE: Where possible create
diff --git a/tools/accessibility/rebase_dump_accessibility_tree_test.py b/tools/accessibility/rebase_dump_accessibility_tree_test.py
index ba5162c..42b3090 100755
--- a/tools/accessibility/rebase_dump_accessibility_tree_test.py
+++ b/tools/accessibility/rebase_dump_accessibility_tree_test.py
@@ -14,12 +14,15 @@
 It collects all of the results from try jobs on all platforms and updates the
 expectation files locally. From there you can run 'git diff' to make sure all
 of the changes look reasonable, then upload the change for code review.
+
+Optional argument: patchset number, otherwise will default to latest patchset
 """
 
 import json
 import os
 import re
 import sys
+import tempfile
 import time
 import urllib
 import urlparse
@@ -35,55 +38,6 @@
 # bother to update the same file twice.
 completed_files = set()
 
-def GitClIssue():
-  '''Retrieve the current issue number as a string.'''
-  result = os.popen('git cl issue').read()
-  # Returns string like: 'Issue number: 12345 (https://...)'
-  return result.split()[2]
-
-def ParseFailure(name, url):
-  '''Parse given the name of a failing trybot and the url of its build log.'''
-  print
-  print "Checking trybot: %s" % name
-  parse_result = urlparse.urlsplit(url)
-  url = "http://chrome-build-extract.appspot.com" + parse_result.path + "?json=1"
-  response = urllib.urlopen(url)
-  if response.getcode() != 200:
-    print 'Error code %d accessing trybot url: %s' % (response.getcode(), url)
-    return
-
-  jsondata = response.read()
-  if not jsondata:
-    print "Failed to fetch from: " + url
-    return
-
-  try:
-    data = json.loads(jsondata)
-  except:
-    print "Failed to parse JSON from: " + url
-    return
-
-  for step in data["steps"]:
-    name = step["name"]
-    if name[:len("content_browsertests")] == "content_browsertests":
-      if name.find("without") >= 0:
-        continue
-      if name.find("retry") >= 0:
-        continue
-      print "Found content_browsertests logs"
-      for log in step["logs"]:
-        (log_name, log_url) = log
-        if log_name == "stdio" or log_name == "swarming.summary" or log_name == "step_metadata":
-          continue
-        log_url += '/text'
-        log_response = urllib.urlopen(log_url)
-        if log_response.getcode() == 200:
-          logdata = log_response.read()
-          print "Parsing test log: %s" % log_name
-          ParseLog(logdata)
-        else:
-          print "Error code %d when fetching test log data from url: %s" % (log_response.getcode(), url)
-
 def Fix(line):
   if line[:3] == '@@@':
     try:
@@ -126,44 +80,55 @@
       test_file = None
       expected_file = None
 
-def ParseTrybots(data):
-  '''Parse the code review page to find links to try bots.'''
-  soup = BeautifulSoup(data)
-  failures = soup.findAll(
-      'a',
-      { "class" : "build-result build-status-color-failure" })
-  print 'Found %d trybots that failed' % len(failures)
-  for f in failures:
-    name = f.text.replace('&nbsp;', '')
-    url = f['href']
-    ParseFailure(name, url)
-
 def Run():
   '''Main. Get the issue number and parse the code review page.'''
   if len(sys.argv) == 2:
-    issue = sys.argv[1]
+    patchSetArg = '--patchset=%s' % sys.argv[1]
   else:
-    issue = GitClIssue()
+    patchSetArg = '';
 
-  url = 'https://codereview.chromium.org/%s' % issue
-  print 'Fetching issue from %s' % url
-  response = urllib.urlopen(url)
-  if response.getcode() != 200:
-    print 'Error code %d accessing url: %s' % (response.getcode(), url)
-    return
-  data = response.read()
-  ParseTrybots(data)
+  (_, tmppath) = tempfile.mkstemp()
+  print 'Temp file: %s' % tmppath
+  os.system('git cl try-results --json %s %s' % (tmppath, patchSetArg))
 
-  print
-  if len(completed_files) == 0:
-    print "No output from DumpAccessibilityTree test results found."
+  try_result = open(tmppath).read()
+  if len(try_result) < 1000:
+    print 'Did not seem to get try bot data.'
+    print try_result
     return
-  else:
-    print "Summary: modified the following files:"
-    all_files = list(completed_files)
-    all_files.sort()
-    for f in all_files:
-      print "* %s" % os.path.relpath(f)
+
+  data = json.loads(try_result)
+  os.unlink(tmppath)
+
+  #print(json.dumps(data, indent=4))
+
+  for builder in data:
+    #print builder['result']
+    if builder['result'] == 'FAILURE':
+      url = builder['url']
+      tokens = url.split('/')
+      bucket = tokens[4]
+      platform = tokens[6]
+      build = tokens[8]
+      logdog_prefix = 'chromium/bb/%s/%s/%s' % (bucket, platform, build)
+      logdog_steps = '%s/+/recipes/steps' % logdog_prefix
+      print logdog_prefix
+      steps = os.popen('cit logdog ls "%s"' % logdog_steps).readlines()
+      a11y_step = None
+      for step in steps:
+        if (step.find('content_browsertests') >= 0 and
+            step.find('with_patch') >= 0 and
+            step.find('trigger') == -1 and
+            step.find('Upload') == -1):
+          a11y_step = step.rstrip()
+      if not a11y_step:
+        print 'No content_browsertests (with patch) step found'
+        continue
+      print a11y_step
+      logdog_cat = ('cit logdog cat -raw "%s/%s/0/stdout"' %
+        (logdog_steps, a11y_step))
+      output = os.popen(logdog_cat).read()
+      ParseLog(output)
 
 if __name__ == '__main__':
   sys.exit(Run())
diff --git a/tools/binary_size/diagnose_bloat.py b/tools/binary_size/diagnose_bloat.py
index b8f033610..c36e2ab 100755
--- a/tools/binary_size/diagnose_bloat.py
+++ b/tools/binary_size/diagnose_bloat.py
@@ -161,9 +161,7 @@
     cmd = [self._RESOURCE_SIZES_PATH, apk_path,'--output-dir', archive_dir,
            '--no-output-dir', '--chartjson']
     if self._slow_options:
-      cmd += ['--estimate-patch-size']
-    else:
-      cmd += ['--no-static-initializer-check']
+      cmd += ['--estimate-patch-size', '--dump-static-initializers']
     _RunCmd(cmd)
     with open(chartjson_file) as f:
       chartjson = json.load(f)
diff --git a/tools/checkteamtags/checkteamtags.py b/tools/checkteamtags/checkteamtags.py
index 02bbe516..40df48a 100755
--- a/tools/checkteamtags/checkteamtags.py
+++ b/tools/checkteamtags/checkteamtags.py
@@ -52,7 +52,7 @@
       team = mappings_file['component-to-team'].get(component)
     else:
       team = None
-    current_mappings[dir_name] = (team, component)
+    current_mappings[dir_name] = {'team': team, 'component': component}
 
   # Extract dir -> (team, component) for affected files
   affected = {}
@@ -73,7 +73,8 @@
   team_to_dir = defaultdict(list)
   errors = {}
   for dir_name, tags in current_mappings.iteritems():
-    team, component = tags
+    team = tags.get('team')
+    component = tags.get('component')
     if component:
       new_dir_to_component[dir_name] = component
     if team:
diff --git a/tools/checkteamtags/extract_components.py b/tools/checkteamtags/extract_components.py
index 1b385cc..697c8070 100755
--- a/tools/checkteamtags/extract_components.py
+++ b/tools/checkteamtags/extract_components.py
@@ -21,7 +21,7 @@
 import os
 import sys
 
-from owners_file_tags import aggregate_components_from_owners
+from owners_file_tags import aggregate_components_from_owners, scrape_owners
 
 
 _DEFAULT_SRC_LOCATION = os.path.join(
@@ -188,8 +188,9 @@
   else:
     root = _DEFAULT_SRC_LOCATION
 
+  scrape_result = scrape_owners(root, include_subdirs=options.include_subdirs)
   mappings, warnings, errors, stats = aggregate_components_from_owners(
-      root, include_subdirs=options.include_subdirs)
+      scrape_result, root, include_subdirs=options.include_subdirs)
   if options.verbose:
     for w in warnings:
       print w
diff --git a/tools/checkteamtags/extract_components_test.py b/tools/checkteamtags/extract_components_test.py
index 186c7b2..54ce53a 100644
--- a/tools/checkteamtags/extract_components_test.py
+++ b/tools/checkteamtags/extract_components_test.py
@@ -11,219 +11,250 @@
 from StringIO import StringIO
 
 import extract_components
+from owners_file_tags_test import mock_file_tree
 
 SRC = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
 sys.path.append(os.path.join(SRC, 'third_party', 'pymock'))
 
 import mock
 
-def mock_file_tree(tree):
-  os_walk_mocks = []
-  file_mocks = {}
-  for path in tree:
-    if tree[path] is not None:
-      os_walk_mocks.append((path, ('ignored'), ('OWNERS', 'dummy.cc')))
-      file_mocks[os.path.join(path, 'OWNERS')] = tree[path]
-    else:
-      os_walk_mocks.append((path, ('ignored'), ('dummy.cc')))
-
-  def custom_mock_open(files_data):
-    def inner_open(path, mode='r'):
-      ret_val = mock.MagicMock()
-      if path in files_data and mode == 'r':
-
-        class mock_opened_file(object):
-          def __enter__(self, *args, **kwargs):
-            return self
-
-          def __iter__(self, *args, **kwargs):
-            return iter(files_data[path].splitlines())
-
-          def __exit__(self, *args, **kwargs):
-            pass
-
-        ret_val = mock_opened_file()
-      return ret_val
-    return inner_open
-
-  def wrapper(func):
-    @mock.patch('owners_file_tags.open', custom_mock_open(file_mocks),
-                create=True)
-    @mock.patch('os.walk', mock.MagicMock(return_value=os_walk_mocks))
-    def inner(*args, **kwargs):
-      return func(*args, **kwargs)
-    return inner
-  return wrapper
-
-
 
 class ExtractComponentsTest(unittest.TestCase):
+  def setUp(self):
+    super(ExtractComponentsTest, self).setUp()
+    self.maxDiff = None
 
-  @mock_file_tree({
-      'src': 'boss@chromium.org\n',
-      'src/dummydir1': 'dummy@chromium.org\n'
-                       '# TEAM: dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir2': 'dummy2@chromium.org\n'
-                       '# TEAM: other-dummy-team@chromium.org\n'
-                       '# COMPONENT: Components>Component2',
-      'src/dummydir1/innerdir1': 'dummy@chromium.org\n'
-                                 '# TEAM: dummy-specialist-team@chromium.org\n'
-                                 '# COMPONENT: Dummy>Component>Subcomponent'})
   def testBaseCase(self):
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      error_code = extract_components.main(['%prog'])
-    self.assertEqual(0, error_code)
-    result_minus_readme = json.loads(saved_output.getvalue())
-    del result_minus_readme['AAA-README']
-    self.assertEqual(result_minus_readme, {
-        'component-to-team': {
-            'Components>Component2': 'other-dummy-team@chromium.org',
-            'Dummy>Component': 'dummy-team@chromium.org',
-            'Dummy>Component>Subcomponent': 'dummy-specialist-team@chromium.org'
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
         },
-        'dir-to-component': {
-            'tools/checkteamtags/src/dummydir1': 'Dummy>Component',
-            'tools/checkteamtags/src/dummydir1/innerdir1':
-                'Dummy>Component>Subcomponent',
-            'tools/checkteamtags/src/dummydir2': 'Components>Component2'
-        }})
+        'dummydir2': {
+            'team': 'other-dummy-team@chromium.org',
+            'component': 'Components>Component2',
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        error_code = extract_components.main(['%prog', 'src'])
+      self.assertEqual(0, error_code)
+      result_minus_readme = json.loads(saved_output.getvalue())
+      del result_minus_readme['AAA-README']
+      self.assertEqual(result_minus_readme, {
+          'component-to-team': {
+              'Components>Component2': 'other-dummy-team@chromium.org',
+              'Dummy>Component': 'dummy-team@chromium.org',
+              'Dummy>Component>Subcomponent':
+                  'dummy-specialist-team@chromium.org'
+          },
+          'dir-to-component': {
+              'dummydir1': 'Dummy>Component',
+              'dummydir1/innerdir1':
+                  'Dummy>Component>Subcomponent',
+              'dummydir2': 'Components>Component2'
+          }})
 
-  @mock_file_tree({
-      'src': 'boss@chromium.org\n',
-      'src/dummydir1': 'dummy@chromium.org\n'
-                       '# TEAM: dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir2': 'dummy2@chromium.org\n'
-                       '# TEAM: other-dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir1/innerdir1': 'dummy@chromium.org\n'
-                                 '# TEAM: dummy-specialist-team@chromium.org\n'
-                                 '# COMPONENT: Dummy>Component>Subcomponent'})
+  def testOsTagBreaksDuplication(self):
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir2': {
+            'team': 'mac-dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+            'os': 'Mac'
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        error_code = extract_components.main(['%prog', 'src'])
+      self.assertEqual(0, error_code)
+      result_minus_readme = json.loads(saved_output.getvalue())
+      del result_minus_readme['AAA-README']
+      self.assertEqual(result_minus_readme, {
+          'component-to-team': {
+              'Dummy>Component': 'dummy-team@chromium.org',
+              'Dummy>Component(Mac)': 'mac-dummy-team@chromium.org',
+              'Dummy>Component>Subcomponent':
+                  'dummy-specialist-team@chromium.org'
+          },
+          'dir-to-component': {
+              'dummydir1': 'Dummy>Component',
+              'dummydir1/innerdir1': 'Dummy>Component>Subcomponent',
+              'dummydir2': 'Dummy>Component(Mac)'
+          }})
+
   def testMultipleTeamsOneComponent(self):
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      error_code = extract_components.main(['%prog', '-w'])
-    self.assertNotEqual(0, error_code)
-    output = saved_output.getvalue()
-    self.assertIn('has more than one team assigned to it', output)
-    self.assertIn('Not writing to file', output)
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir2': {
+            'team': 'other-dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        error_code = extract_components.main(['%prog', '-w', 'src'])
+      self.assertNotEqual(0, error_code)
+      output = saved_output.getvalue()
+      self.assertIn('has more than one team assigned to it', output)
+      self.assertIn('Not writing to file', output)
 
-  @mock_file_tree({
-      'src': 'boss@chromium.org\n',
-      'src/dummydir1': 'dummy@chromium.org\n'
-                       '# TEAM: dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir2': 'dummy2@chromium.org\n'
-                       '# TEAM: other-dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir1/innerdir1': 'dummy@chromium.org\n'
-                                 '# TEAM: dummy-specialist-team@chromium.org\n'
-                                 '# COMPONENT: Dummy>Component>Subcomponent'})
   def testVerbose(self):
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      extract_components.main(['%prog', '-v'])
-    output = saved_output.getvalue()
-    self.assertIn('src/OWNERS has no COMPONENT tag', output)
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir2': {
+            'team': 'other-dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        extract_components.main(['%prog', '-v', 'src'])
+      output = saved_output.getvalue()
+      self.assertIn('./OWNERS has no COMPONENT tag', output)
 
-  @mock_file_tree({
-      'src': 'boss@chromium.org\n',
-      'src/dummydir1': 'dummy@chromium.org\n'
-                       '# TEAM: dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir2': 'dummy2@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir1/innerdir1': 'dummy@chromium.org\n'
-                                 '# TEAM: dummy-specialist-team@chromium.org\n'
-                                 '# COMPONENT: Dummy>Component>Subcomponent'})
   def testCoverage(self):
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      extract_components.main(['%prog', '-s 2'])
-    output = saved_output.getvalue()
-    self.assertIn('4 OWNERS files in total.', output)
-    self.assertIn('3 (75.00%) OWNERS files have COMPONENT', output)
-    self.assertIn('2 (50.00%) OWNERS files have TEAM and COMPONENT', output)
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir2': {
+            'component': 'Dummy>Component',
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        extract_components.main(['%prog', '-s 2', 'src'])
+      output = saved_output.getvalue()
+      self.assertIn('4 OWNERS files in total.', output)
+      self.assertIn('3 (75.00%) OWNERS files have COMPONENT', output)
+      self.assertIn('2 (50.00%) OWNERS files have TEAM and COMPONENT', output)
 
-  @mock_file_tree({
-      'src': 'boss@chromium.org\n',
-      'src/dummydir1': 'dummy@chromium.org\n'
-                       '# TEAM: dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir2': 'dummy2@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir1/innerdir1': 'dummy@chromium.org\n'
-                                 '# TEAM: dummy-specialist-team@chromium.org\n'
-                                 '# COMPONENT: Dummy>Component>Subcomponent'})
   def testCompleteCoverage(self):
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      extract_components.main(['%prog', '-c'])
-    output = saved_output.getvalue()
-    self.assertIn('4 OWNERS files in total.', output)
-    self.assertIn('3 (75.00%) OWNERS files have COMPONENT', output)
-    self.assertIn('2 (50.00%) OWNERS files have TEAM and COMPONENT', output)
-    self.assertIn('4 OWNERS files at depth 0', output)
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir2': {
+            'component': 'Dummy>Component',
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        extract_components.main(['%prog', '-c', ''])
+      output = saved_output.getvalue()
+      self.assertIn('4 OWNERS files in total.', output)
+      self.assertIn('3 (75.00%) OWNERS files have COMPONENT', output)
+      self.assertIn('2 (50.00%) OWNERS files have TEAM and COMPONENT', output)
+      self.assertIn('1 OWNERS files at depth 0', output)
+      self.assertIn('2 OWNERS files at depth 1', output)
+      self.assertIn('1 OWNERS files at depth 2', output)
 
-  # We use OrderedDict here to guarantee that mocked version of os.walk returns
-  # directories in the specified order (top-down).
-  @mock_file_tree(OrderedDict([
-      ('chromium/src', 'boss@chromium.org\n'),
-      ('chromium/src/dir1', 'dummy@chromium.org\n'
-                            '# TEAM: dummy-team@chromium.org\n'
-                            '# COMPONENT: Dummy>Component'),
-      ('chromium/src/dir2', 'dummy2@chromium.org\n'
-                            '# TEAM: other-dummy-team@chromium.org\n'
-                            '# COMPONENT: Dummy>Component2'),
-      ('chromium/src/dir1/subdir', 'dummy@chromium.org'),
-      ('chromium/src/dir2/subdir', None),
-      ('third_party/WebKit/LayoutTests/foo',
-           '# TEAM: dummy-team-3@chromium.org\n'),
-      ('third_party/WebKit/LayoutTests/bar',
-           '# TEAM: dummy-team-3@chromium.org\n'
-           '# COMPONENT: Dummy>Component3\n'),
-  ]))
   def testIncludesSubdirectoriesWithNoOwnersFileOrNoComponentTag(self):
-    self.maxDiff = None  # This helps to see assertDictEqual errors in full.
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      error_code = extract_components.main(['%prog', '--include-subdirs', ''])
-    self.assertEqual(0, error_code)
-    result_minus_readme = json.loads(saved_output.getvalue())
-    del result_minus_readme['AAA-README']
-    self.assertDictEqual(result_minus_readme, {
-        u'component-to-team': {
-            u'Dummy>Component': u'dummy-team@chromium.org',
-            u'Dummy>Component2': u'other-dummy-team@chromium.org',
-            u'Dummy>Component3': u'dummy-team-3@chromium.org',
-        },
-        u'dir-to-component': {
-            u'chromium/src/dir1': u'Dummy>Component',
-            u'chromium/src/dir1/subdir': u'Dummy>Component',
-            u'chromium/src/dir2': u'Dummy>Component2',
-            u'chromium/src/dir2/subdir': u'Dummy>Component2',
-            u'third_party/WebKit/LayoutTests/bar': u'Dummy>Component3',
-        },
-        u'dir-to-team': {
-            u'third_party/WebKit/LayoutTests/foo': u'dummy-team-3@chromium.org',
-        }})
+    # We use OrderedDict here to guarantee that mocked version of os.walk
+    # returns directories in the specified order (top-down).
+    with mock_file_tree(OrderedDict([
+        ('chromium/src', 'boss@chromium.org\n'),
+        ('chromium/src/dir1', 'dummy@chromium.org\n'
+                              '# TEAM: dummy-team@chromium.org\n'
+                              '# COMPONENT: Dummy>Component'),
+        ('chromium/src/dir2', 'dummy2@chromium.org\n'
+                              '# TEAM: other-dummy-team@chromium.org\n'
+                              '# COMPONENT: Dummy>Component2'),
+        ('chromium/src/dir1/subdir', 'dummy@chromium.org'),
+        ('chromium/src/dir2/subdir', None),
+        ('third_party/WebKit/LayoutTests/foo',
+             '# TEAM: dummy-team-3@chromium.org\n'),
+        ('third_party/WebKit/LayoutTests/bar',
+             '# TEAM: dummy-team-3@chromium.org\n'
+             '# COMPONENT: Dummy>Component3\n'),
+    ])):
+      # TODO(robertocn): remove this testcase and the auxiliary function
+      # mock_file_tree (that has been moved to owners_file_tags_test) when
+      # sergiyb's scripts are using the data directly from scrape_owners.
+      self.maxDiff = None  # This helps to see assertDictEqual errors in full.
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        error_code = extract_components.main(['%prog', '--include-subdirs', ''])
+      self.assertEqual(0, error_code)
+      result_minus_readme = json.loads(saved_output.getvalue())
+      del result_minus_readme['AAA-README']
+      self.assertDictEqual(result_minus_readme, {
+          u'component-to-team': {
+              u'Dummy>Component': u'dummy-team@chromium.org',
+              u'Dummy>Component2': u'other-dummy-team@chromium.org',
+              u'Dummy>Component3': u'dummy-team-3@chromium.org',
+          },
+          u'dir-to-component': {
+              u'chromium/src/dir1': u'Dummy>Component',
+              u'chromium/src/dir1/subdir': u'Dummy>Component',
+              u'chromium/src/dir2': u'Dummy>Component2',
+              u'chromium/src/dir2/subdir': u'Dummy>Component2',
+              u'third_party/WebKit/LayoutTests/bar': u'Dummy>Component3',
+          },
+          u'dir-to-team': {
+              u'third_party/WebKit/LayoutTests/foo':
+                  u'dummy-team-3@chromium.org',
+          }})
 
-  @mock_file_tree({
-      'src': 'boss@chromium.org\n',
-      'src/dummydir1': 'dummy@chromium.org\n'
-                       '# TEAM: dummy-team@chromium.org\n'
-                       '# COMPONENT: Dummy>Component',
-      'src/dummydir1/innerdir1': 'dummy@chromium.org\n'
-                                 '# TEAM: dummy-specialist-team@chromium.org\n'
-                                 '# COMPONENT: Dummy>Component>Subcomponent'})
   def testDisplayFile(self):
-    saved_output = StringIO()
-    with mock.patch('sys.stdout', saved_output):
-      extract_components.main(['%prog', '-m 2'])
-    output = saved_output.getvalue()
-    self.assertIn('OWNERS files that have missing team and component by depth:',
-                  output)
-    self.assertIn('at depth 0', output)
-    self.assertIn('[\'tools/checkteamtags/src/OWNERS\']', output)
+    with mock.patch('extract_components.scrape_owners', return_value={
+        '.': {},
+        'dummydir1': {
+            'team': 'dummy-team@chromium.org',
+            'component': 'Dummy>Component',
+        },
+        'dummydir1/innerdir1': {
+            'team': 'dummy-specialist-team@chromium.org',
+            'component': 'Dummy>Component>Subcomponent'
+        }
+    }):
+      saved_output = StringIO()
+      with mock.patch('sys.stdout', saved_output):
+        extract_components.main(['%prog', '-m 2', 'src'])
+      output = saved_output.getvalue()
+      self.assertIn('OWNERS files that have missing team and component '
+                    'by depth:', output)
+      self.assertIn('at depth 0', output)
+      self.assertIn('[\'./OWNERS\']', output)
diff --git a/tools/checkteamtags/owners_file_tags.py b/tools/checkteamtags/owners_file_tags.py
index 941b368f..2bae6b44 100644
--- a/tools/checkteamtags/owners_file_tags.py
+++ b/tools/checkteamtags/owners_file_tags.py
@@ -14,29 +14,42 @@
   Args:
     filename (str): path to the file to parse.
   Returns:
-    (team (str), component(str)): The team and component found in the file, the
-        last one of each if multiple, None if missing.
-  """
-  team = None
-  component = None
+    a dict with the following format, with any subset of the listed keys:
+    {
+        'component': 'component>name',
+        'team': 'team@email.here',
+        'os': 'Linux|Windows|Mac|Android|Chrome|Fuchsia'
+    }
+ """
   team_regex = re.compile('\s*#\s*TEAM\s*:\s*(\S+)')
   component_regex = re.compile('\s*#\s*COMPONENT\s*:\s*(\S+)')
+  os_regex = re.compile('\s*#\s*OS\s*:\s*(\S+)')
+  result = {}
   with open(filename) as f:
     for line in f:
       team_matches = team_regex.match(line)
       if team_matches:
-        team = team_matches.group(1)
+        result['team'] = team_matches.group(1)
       component_matches = component_regex.match(line)
       if component_matches:
-        component = component_matches.group(1)
-  return team, component
+        result['component'] = component_matches.group(1)
+      os_matches = os_regex.match(line)
+      if os_matches:
+        result['os'] = os_matches.group(1)
+  return result
 
 
-def aggregate_components_from_owners(root, include_subdirs=False):
-  """Traverses the given dir and parse OWNERS files for team and component tags.
+def aggregate_components_from_owners(all_owners_data, root,
+                                     include_subdirs=False):
+  """Converts the team/component/os tags parsed from OWNERS into mappings.
 
   Args:
+    all_owners_data (dict): A mapping from relative path to a dir to a dict
+        mapping the tag names to their values. See docstring for scrape_owners.
     root (str): the path to the src directory.
+    include_subdirs (bool): Deprecated, whether to generate the additional
+        dir-to-team mapping. This mapping is being replaced by the result of
+        scrape_owners below.
 
   Returns:
     A tuple (data, warnings, errors, stats) where data is a dict of the form
@@ -66,37 +79,41 @@
   # TODO(sergiyb): Remove this mapping. Please do not use it as it is going to
   # be removed in the future. See http://crbug.com/702202.
   dir_to_team = {}
-  for dirname, _, files in os.walk(root):
-    # Proofing against windows casing oddities.
-    owners_file_names = [f for f in files if f.upper() == 'OWNERS']
-    rel_dirname = os.path.relpath(dirname, root)
-    if owners_file_names:
-      file_depth = dirname[len(root) + len(os.path.sep):].count(os.path.sep)
-      num_total += 1
-      num_total_by_depth[file_depth] += 1
-      owners_full_path = os.path.join(dirname, owners_file_names[0])
-      owners_rel_path = os.path.relpath(owners_full_path, root)
-      team, component = parse(owners_full_path)
-      if component:
-        num_with_component += 1
-        num_with_component_by_depth[file_depth] += 1
-        dir_to_component[rel_dirname] = component
-        if team:
-          num_with_team_component += 1
-          num_with_team_component_by_depth[file_depth] += 1
-          component_to_team[component].add(team)
-      else:
-        warnings.append('%s has no COMPONENT tag' % owners_rel_path)
-        if not team:
-          dir_missing_info_by_depth[file_depth].append(owners_rel_path)
+  for rel_dirname, owners_data in all_owners_data.iteritems():
+    # We apply relpath to remove any possible `.` and `..` chunks and make
+    # counting separators work correctly as a means of obtaining the file_depth.
+    rel_path = os.path.relpath(rel_dirname, root)
+    file_depth = 0 if rel_path == '.' else rel_path.count(os.path.sep) + 1
+    num_total += 1
+    num_total_by_depth[file_depth] += 1
+    component = owners_data.get('component')
+    team = owners_data.get('team')
+    os_tag = owners_data.get('os')
+    if os_tag and component:
+      component = '%s(%s)' % (component, os_tag)
+    if component:
+      num_with_component += 1
+      num_with_component_by_depth[file_depth] += 1
+      dir_to_component[rel_dirname] = component
+      if team:
+        num_with_team_component += 1
+        num_with_team_component_by_depth[file_depth] += 1
+        component_to_team[component].add(team)
+    else:
+      rel_owners_path = os.path.join(rel_dirname, 'OWNERS')
+      warnings.append('%s has no COMPONENT tag' % rel_owners_path)
+      if not team and not os_tag:
+        dir_missing_info_by_depth[file_depth].append(rel_owners_path)
 
-      # Add dir-to-team mapping unless there is also dir-to-component mapping.
-      if (include_subdirs and team and not component and
-          rel_dirname.startswith('third_party/WebKit/LayoutTests')):
-        dir_to_team[rel_dirname] = team
+    # TODO(robertocn): Remove the dir-to-team mapping once the raw owners data
+    # is being exported in its own file and being used by sergiyb's scripts.
+    # Add dir-to-team mapping unless there is also dir-to-component mapping.
+    if (include_subdirs and team and not component and
+        rel_dirname.startswith('third_party/WebKit/LayoutTests')):
+      dir_to_team[rel_dirname] = team
 
     if include_subdirs and rel_dirname not in dir_to_component:
-      rel_parent_dirname = os.path.relpath(os.path.dirname(dirname), root)
+      rel_parent_dirname = os.path.relpath(rel_dirname, root)
       if rel_parent_dirname in dir_to_component:
         dir_to_component[rel_dirname] = dir_to_component[rel_parent_dirname]
       if rel_parent_dirname in dir_to_team:
@@ -137,3 +154,41 @@
   for c in mappings['component-to-team']:
     mappings['component-to-team'][c] = mappings['component-to-team'][c].pop()
   return mappings
+
+def scrape_owners(root, include_subdirs):
+  """Recursively parse OWNERS files for tags.
+
+  Args:
+    root (str): The directory where to start parsing.
+    include_subdirs (bool): Whether to generate entries for subdirs with no
+        own OWNERS files based on the parent dir's tags.
+
+  Returns a dict in the form below.
+  {
+      '/path/to/dir': {
+          'component': 'component>name',
+          'team': 'team@email.here',
+          'os': 'Linux|Windows|Mac|Android|Chrome|Fuchsia'
+      },
+      '/path/to/dir/inside/dir': {
+          'component': ...
+      }
+  }
+  """
+  data = {}
+  for dirname, _, files in os.walk(root):
+    # Proofing against windows casing oddities.
+    owners_file_names = [f for f in files if f.upper() == 'OWNERS']
+    rel_dirname = os.path.relpath(dirname, root)
+    if owners_file_names:
+      owners_full_path = os.path.join(dirname, owners_file_names[0])
+      data[rel_dirname] = parse(owners_full_path)
+    if include_subdirs and not data.get(rel_dirname):
+      parent_dirname = os.path.dirname(dirname)
+      # In the case where the root doesn't have an OWNERS file, don't try to
+      # check its parent.
+      if parent_dirname:
+        rel_parent_dirname = os.path.relpath(parent_dirname , root)
+        if rel_parent_dirname in data:
+          data[rel_dirname] = data[rel_parent_dirname]
+  return data
diff --git a/tools/checkteamtags/owners_file_tags_test.py b/tools/checkteamtags/owners_file_tags_test.py
new file mode 100644
index 0000000..4218b76
--- /dev/null
+++ b/tools/checkteamtags/owners_file_tags_test.py
@@ -0,0 +1,139 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from collections import OrderedDict
+from contextlib import contextmanager
+import os
+import sys
+import unittest
+
+import owners_file_tags
+
+SRC = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
+sys.path.append(os.path.join(SRC, 'third_party', 'pymock'))
+
+import mock
+
+@contextmanager
+def mock_file_tree(tree):
+  os_walk_mocks = []
+  file_mocks = {}
+  for path in tree:
+    if tree[path] is not None:
+      os_walk_mocks.append((path, ('ignored'), ('OWNERS', 'dummy.cc')))
+      file_mocks[os.path.join(path, 'OWNERS')] = tree[path]
+    else:
+      os_walk_mocks.append((path, ('ignored'), ('dummy.cc')))
+
+  def custom_mock_open(files_data):
+    def inner_open(path, mode='r'):
+      ret_val = mock.MagicMock()
+      if path in files_data and mode == 'r':
+
+        class mock_opened_file(object):
+          def __enter__(self, *args, **kwargs):
+            return self
+
+          def __iter__(self, *args, **kwargs):
+            return iter(files_data[path].splitlines())
+
+          def __exit__(self, *args, **kwargs):
+            pass
+
+        ret_val = mock_opened_file()
+      return ret_val
+    return inner_open
+
+  patchers = [
+      mock.patch(
+          'owners_file_tags.open', custom_mock_open(file_mocks), create=True),
+      mock.patch('os.walk', mock.MagicMock(return_value=os_walk_mocks))
+  ]
+  for patcher in patchers:
+    patcher.start()
+  yield
+  for patcher in patchers:
+    patcher.stop()
+
+
+class OwnersFileTagsTest(unittest.TestCase):
+
+  """os tag breaking dupe >>"""
+  def setUp(self):
+    super(OwnersFileTagsTest, self).setUp()
+    self.maxDiff = None
+
+  def testScrapeOwners(self):
+    with mock_file_tree({
+        'src': 'boss@chromium.org\n',
+        'src/dummydir1':
+            'dummy@chromium.org\n'
+            '# TEAM: dummy-team@chromium.org\n'
+            '# COMPONENT: Dummy>Component\n',
+        'src/dummydir1/innerdir1':
+            'dummy@chromium.org\n'
+            '# TEAM: dummy-specialist-team@chromium.org\n',
+        'src/dummydir1/innerdir2':
+            'dummy@chromium.org\n'
+            '# COMPONENT: Dummy>Component>Subcomponent\n',
+        'src/dummydir1/innerdir3':
+            'dummy@chromium.org\n'
+             '# OS: Mac\n'
+    }):
+      scraped_data = owners_file_tags.scrape_owners('src', False)
+      self.assertEqual({
+          '.': {},
+          'dummydir1': {
+              'team': 'dummy-team@chromium.org',
+              'component': 'Dummy>Component',
+          },
+          'dummydir1/innerdir1': {
+              'team': 'dummy-specialist-team@chromium.org',
+          },
+          'dummydir1/innerdir2': {
+              'component': 'Dummy>Component>Subcomponent'
+          },
+          'dummydir1/innerdir3': {
+              'os': 'Mac'
+          }
+      }, scraped_data)
+
+  def testScrapeOwnersWithSubdirectories(self):
+    with mock_file_tree(OrderedDict([
+        ('src', 'boss@chromium.org\n'),
+        ('src/dummydir1',
+         'dummy@chromium.org\n'
+         '# TEAM: dummy-team@chromium.org\n'
+         '# COMPONENT: Dummy>Component\n'),
+        ('src/dummydir1/innerdir1',
+         'dummy@chromium.org\n'
+         '# TEAM: dummy-specialist-team@chromium.org\n'),
+        ('src/dummydir1/innerdir2',
+         'dummy@chromium.org\n'
+         '# COMPONENT: Dummy>Component>Subcomponent\n'),
+        ('src/dummydir1/innerdir3',
+         'dummy@chromium.org\n# OS: Mac\n'),
+        ('src/dummydir1/innerdir4', None),
+    ])):
+      scraped_data = owners_file_tags.scrape_owners('src', True)
+      self.assertEqual({
+          '.': {},
+          'dummydir1': {
+              'team': 'dummy-team@chromium.org',
+              'component': 'Dummy>Component',
+          },
+          'dummydir1/innerdir1': {
+              'team': 'dummy-specialist-team@chromium.org',
+          },
+          'dummydir1/innerdir2': {
+              'component': 'Dummy>Component>Subcomponent'
+          },
+          'dummydir1/innerdir3': {
+              'os': 'Mac'
+          },
+          'dummydir1/innerdir4': {
+              'team': 'dummy-team@chromium.org',
+              'component': 'Dummy>Component',
+          },
+      }, scraped_data )
diff --git a/tools/gn/analyzer.cc b/tools/gn/analyzer.cc
index d1f2d524..aa0eca4d 100644
--- a/tools/gn/analyzer.cc
+++ b/tools/gn/analyzer.cc
@@ -395,9 +395,7 @@
 void Analyzer::AddTargetsDirectlyReferringToFileTo(const SourceFile* file,
                                                    TargetSet* matches) const {
   for (auto* target : all_targets_) {
-    // Only handles targets in the default toolchain.
-    if ((target->label().GetToolchainLabel() == default_toolchain_) &&
-        TargetRefersToFile(target, file))
+    if (TargetRefersToFile(target, file))
       matches->insert(target);
   }
 }
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index 735e5f9..2e6aa6f6 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -5111,7 +5111,7 @@
   For binary targets (source sets, executables, and libraries), the known file
   types will be compiled with the associated tools. Unknown file types and
   headers will be skipped. However, you should still list all C/C+ header files
-  so GN knows about the existance of those files for the purposes of include
+  so GN knows about the existence of those files for the purposes of include
   checking.
 
   As a special case, a file ending in ".def" will be treated as a Windows
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc
index d304bc50..bbb8791 100644
--- a/tools/gn/variables.cc
+++ b/tools/gn/variables.cc
@@ -1715,7 +1715,7 @@
   For binary targets (source sets, executables, and libraries), the known file
   types will be compiled with the associated tools. Unknown file types and
   headers will be skipped. However, you should still list all C/C+ header files
-  so GN knows about the existance of those files for the purposes of include
+  so GN knows about the existence of those files for the purposes of include
   checking.
 
   As a special case, a file ending in ".def" will be treated as a Windows
diff --git a/tools/licenses.py b/tools/licenses.py
index ec63ff4..9f33ffb8 100755
--- a/tools/licenses.py
+++ b/tools/licenses.py
@@ -555,12 +555,11 @@
             template = template.replace('{{%s}}' % key, val)
         return template
 
-    def MetadataToTemplateEntry(metadata, entry_template, entry_id):
+    def MetadataToTemplateEntry(metadata, entry_template):
         env = {
             'name': metadata['Name'],
             'url': metadata['URL'],
             'license': open(metadata['License File'], 'rb').read(),
-            'id': str(entry_id),
         }
         return {
             'name': metadata['Name'],
@@ -588,7 +587,6 @@
                                            'about_credits_entry.tmpl')
 
     entry_template = open(entry_template_file).read()
-    entry_id = 0
     entries = []
     # Start from Chromium's LICENSE file
     chromium_license_metadata = {
@@ -596,8 +594,7 @@
         'URL': 'http://www.chromium.org',
         'License File': os.path.join(_REPOSITORY_ROOT, 'LICENSE') }
     entries.append(MetadataToTemplateEntry(chromium_license_metadata,
-        entry_template, entry_id))
-    entry_id += 1
+        entry_template))
 
     for path in third_party_dirs:
         try:
@@ -615,11 +612,11 @@
             # updated to provide --gn-target to this script.
             if path in KNOWN_NON_IOS_LIBRARIES:
                 continue
-        entries.append(MetadataToTemplateEntry(metadata, entry_template,
-            entry_id))
-        entry_id += 1
+        entries.append(MetadataToTemplateEntry(metadata, entry_template))
 
     entries.sort(key=lambda entry: (entry['name'], entry['content']))
+    for entry_id, entry in enumerate(entries):
+        entry['content'] = entry['content'].replace('{{id}}', str(entry_id))
 
     entries_contents = '\n'.join([entry['content'] for entry in entries])
     file_template = open(file_template_file).read()
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 9fd1f81f..099d7ca 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -13375,7 +13375,7 @@
 </enum>
 
 <enum name="FeatureObserver" type="int">
-<!-- Generated from third_party/WebKit/public/platform/UseCounterFeature.def -->
+<!-- Generated from third_party/WebKit/public/platform/WebFeature.h -->
 
   <int value="0" label="OBSOLETE_PageDestruction"/>
   <int value="1" label="LegacyNotifications"/>
@@ -16312,6 +16312,15 @@
   <int value="7" label="File contents internally deleted."/>
 </enum>
 
+<enum name="FileMetricsProviderEmbeddedProfileResult" type="int">
+  <int value="0" label="File was accessed."/>
+  <int value="1" label="File had embedded profile."/>
+  <int value="2"
+      label="File used fallback because no embedded profile was found."/>
+  <int value="3"
+      label="File was dropped because no embedded profile was found."/>
+</enum>
+
 <enum name="FileReaderSyncWorkerType" type="int">
   <int value="0" label="Other"/>
   <int value="1" label="Dedicated Worker"/>
@@ -22013,6 +22022,7 @@
   <int value="-1832575380" label="show-saved-copy"/>
   <int value="-1832221649" label="disable-out-of-process-pac"/>
   <int value="-1821058653" label="enable-delay-agnostic-aec"/>
+  <int value="-1817209284" label="PayWithGoogleV1:enabled"/>
   <int value="-1812579951" label="ContentSuggestionsCategoryRanker:enabled"/>
   <int value="-1811394154" label="disable-webrtc-hw-vp8-encoding"/>
   <int value="-1810294310" label="AndroidPaymentApps:enabled"/>
@@ -22916,6 +22926,7 @@
   <int value="1416592483" label="ash-enable-mirrored-screen"/>
   <int value="1418054870" label="SpecialLocale:enabled"/>
   <int value="1421620678" label="simple-clear-browsing-data-support-string"/>
+  <int value="1431050645" label="PayWithGoogleV1:disabled"/>
   <int value="1435018419" label="AutofillUpstreamRequestCvcIfMissing:disabled"/>
   <int value="1441897340" label="AndroidSpellCheckerNonLowEnd:enabled"/>
   <int value="1442798825" label="enable-quic"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 3064958..f3310ae 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -78703,6 +78703,15 @@
   </summary>
 </histogram>
 
+<histogram name="UMA.FileMetricsProvider.EmbeddedProfileResult"
+    enum="FileMetricsProviderEmbeddedProfileResult">
+  <owner>asvitkine@chromium.org</owner>
+  <owner>bcwhite@chromium.org</owner>
+  <summary>
+    Records attempts to upload metrics from files with embedded system profiles.
+  </summary>
+</histogram>
+
 <histogram name="UMA.FileMetricsProvider.InitialAccessResult"
     enum="FileMetricsProviderAccessResult">
   <owner>asvitkine@chromium.org</owner>
diff --git a/tools/metrics/histograms/update_use_counter_feature_enum.py b/tools/metrics/histograms/update_use_counter_feature_enum.py
index 4213288..e26c2695 100755
--- a/tools/metrics/histograms/update_use_counter_feature_enum.py
+++ b/tools/metrics/histograms/update_use_counter_feature_enum.py
@@ -32,9 +32,9 @@
                     'https://github.com/GoogleChrome/chromium-dashboard')
   options, args = parser.parse_args()
 
-  source_path = 'third_party/WebKit/public/platform/UseCounterFeature.def'
+  source_path = 'third_party/WebKit/public/platform/WebFeature.h'
 
-  START_MARKER = '^'
+  START_MARKER = '^enum class WebFeature : uint32_t {'
   END_MARKER = '^kNumberOfFeatures'
 
   if options.dashboard:
diff --git a/tools/perf/docs/apk_size_regressions.md b/tools/perf/docs/apk_size_regressions.md
index a39a748a..7b0c959d 100644
--- a/tools/perf/docs/apk_size_regressions.md
+++ b/tools/perf/docs/apk_size_regressions.md
@@ -27,7 +27,7 @@
 
 **Example:**
 
-     tools/binary_size/diagnose_bloat.py AFTER_REV --reference-rev BEFORE_REV --subrepo v8 --all
+     tools/binary_size/diagnose_bloat.py AFTER_GIT_REV --reference-rev BEFORE_GIT_REV --subrepo v8 --all
 
 ### Monochrome.apk Alerts
 
@@ -45,32 +45,39 @@
 
 ## Step 2: File Bug or Silence Alert
 
-If the code seems to justify the size increase:
+If the code clearly justifies the size increase, silence the alert.
 
- * Annotate the code review with the following (replacing **bold** parts):
-    > FYI - this added **20kb** to Chrome on Android. No action is required
-    > (unless you can think of an obvious way to reduce the overhead).
-    >
-    > Link to size graph:
-[https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074)
- * Silence the alert.
+Otherwise, file a bug (TODO: [Make this template automatic](https://github.com/catapult-project/catapult/issues/3150)):
 
+ * Change the bug's title from `X%` to `XXkb`
+ * Assign to commit author
+ * Set description to (replacing **bold** parts):
+   > Caused by "**First line of commit message**"
+   >
+   > Commit: **abc123abc123abc123abc123abc123abc123abcd**
+   >
+   > Link to size graph:
+   > [https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074)
+   >
+   > Debugging size regressions is documented at:
+   > https://chromium.googlesource.com/chromium/src/+/master/tools/perf/docs/apk_size_regressions.md#Debugging-Apk-Size-Increase
+   >
+   > **Optional:**
+   >
+   > It looks to me that the size increase is expected. Feel free to close as
+   > "Won't Fix", unless you can see some way to reduce size.
+   >
+   > **Optional:**
+   >
+   > It looks like there is something that could be done to reduce the size
+   > here. Adding ReleaseBlock-Stable.
 
-If the code might not justify the size increase:
-
- * File a bug (TODO:
-[Make this template automatic](https://github.com/catapult-project/catapult/issues/3150)).
-    * Change the bug's title from `X%` to `XXkb`
-    * Assign to commit author
-    * Set description to (replacing **bold** parts):
-      > Caused by "**First line of commit message**"
-      > Commit: **abc123abc123abc123abc123abc123abc123abcd**
-      >
-      > Link to size graph:
-[https://chromeperf.appspot.com/report?sid=a097e74b1aa288511afb4cb616efe0f95ba4d347ad61d5e835072f23450938ba&rev=**440074**](https://chromeperf.appspot.com/report?sid=cfc29eed1238fd38fb5e6cf83bdba6c619be621b606e03e5dfc2e99db14c418b&rev=440074)
-      >
-      > How to debug this size regressions is documented at:
-https://chromium.googlesource.com/chromium/src/+/master/tools/perf/docs/apk_size_regressions.md#Debugging-Apk-Size-Increase
+Optional, but encouraged:
+ * In a follow-up comment, run:
+   ``` sh
+   tools/binary_size/diagnose_bloat.py GIT_REV --cloud
+   ```
+ * Paste relevant output into the bug.
 
 # Debugging Apk Size Increase
 
@@ -87,6 +94,10 @@
  * There is likely nothing that can be done. Translations are expensive.
  * Close as `Won't Fix`.
 
+### Growth is from Native Resources (pak files)
+
+ * Ensure `compress="gzip"` is used for all `chrome:` pages.
+
 ### Growth is from Images
 
   * Would [a VectorDrawable](https://codereview.chromium.org/2857893003/) be better?
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc
index 9633deea..4241f46 100644
--- a/ui/app_list/app_list_constants.cc
+++ b/ui/app_list/app_list_constants.cc
@@ -91,6 +91,7 @@
 
 // The number of apps shown in the start page app grid.
 const size_t kNumStartPageTiles = 9;
+const size_t kNumStartPageTilesFullscreen = 5;
 
 // Maximum number of results to show in the launcher Search UI.
 const size_t kMaxSearchResults = 6;
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h
index 7e6cb28..a3927e9 100644
--- a/ui/app_list/app_list_constants.h
+++ b/ui/app_list/app_list_constants.h
@@ -71,6 +71,7 @@
 APP_LIST_EXPORT extern const SkColor kIconColor;
 
 APP_LIST_EXPORT extern const size_t kNumStartPageTiles;
+APP_LIST_EXPORT extern const size_t kNumStartPageTilesFullscreen;
 APP_LIST_EXPORT extern const size_t kMaxSearchResults;
 
 APP_LIST_EXPORT extern const int kReorderDroppingCircleRadius;
diff --git a/ui/app_list/presenter/app_list_presenter_impl.cc b/ui/app_list/presenter/app_list_presenter_impl.cc
index 9fa5613f..c4ef3092 100644
--- a/ui/app_list/presenter/app_list_presenter_impl.cc
+++ b/ui/app_list/presenter/app_list_presenter_impl.cc
@@ -59,8 +59,10 @@
     return;
 
   is_visible_ = true;
-  if (app_list_)
+  if (app_list_) {
     app_list_->OnTargetVisibilityChanged(GetTargetVisibility());
+    app_list_->OnVisibilityChanged(GetTargetVisibility(), display_id);
+  }
 
   if (view_) {
     ScheduleAnimation();
@@ -86,9 +88,10 @@
   DCHECK(view_);
 
   is_visible_ = false;
-  if (app_list_)
+  if (app_list_) {
     app_list_->OnTargetVisibilityChanged(GetTargetVisibility());
-
+    app_list_->OnVisibilityChanged(GetTargetVisibility(), GetDisplayId());
+  }
   // The dismissal may have occurred in response to the app list losing
   // activation. Otherwise, our widget is currently active. When the animation
   // completes we'll hide the widget, changing activation. If a menu is shown
diff --git a/ui/app_list/views/all_apps_tile_item_view.cc b/ui/app_list/views/all_apps_tile_item_view.cc
index a2bfb8a..fd21536 100644
--- a/ui/app_list/views/all_apps_tile_item_view.cc
+++ b/ui/app_list/views/all_apps_tile_item_view.cc
@@ -6,7 +6,9 @@
 
 #include "base/metrics/histogram_macros.h"
 #include "ui/app_list/app_list_constants.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/app_list/resources/grit/app_list_resources.h"
+#include "ui/app_list/views/app_list_view.h"
 #include "ui/app_list/views/contents_view.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/resource/resource_bundle.h"
@@ -38,8 +40,9 @@
 
 }  // namespace
 
-AllAppsTileItemView::AllAppsTileItemView(ContentsView* contents_view)
-    : contents_view_(contents_view) {
+AllAppsTileItemView::AllAppsTileItemView(ContentsView* contents_view,
+                                         AppListView* app_list_view)
+    : contents_view_(contents_view), app_list_view_(app_list_view) {
   SetTitle(l10n_util::GetStringUTF16(IDS_APP_LIST_ALL_APPS));
   SetHoverStyle(TileItemView::HOVER_STYLE_ANIMATE_SHADOW);
   UpdateIcon();
@@ -64,6 +67,8 @@
                             AppListModel::STATE_LAST);
 
   contents_view_->SetActiveState(AppListModel::STATE_APPS);
+  if (features::IsFullscreenAppListEnabled())
+    app_list_view_->SetState(AppListView::FULLSCREEN);
 }
 
 }  // namespace app_list
diff --git a/ui/app_list/views/all_apps_tile_item_view.h b/ui/app_list/views/all_apps_tile_item_view.h
index a3cf94b..aa52351 100644
--- a/ui/app_list/views/all_apps_tile_item_view.h
+++ b/ui/app_list/views/all_apps_tile_item_view.h
@@ -11,12 +11,13 @@
 
 namespace app_list {
 
+class AppListView;
 class ContentsView;
 
 // A tile item for the "All apps" button on the start page.
 class AllAppsTileItemView : public TileItemView {
  public:
-  explicit AllAppsTileItemView(ContentsView* contents_view);
+  AllAppsTileItemView(ContentsView* contents_view, AppListView* app_list_view);
 
   ~AllAppsTileItemView() override;
 
@@ -27,6 +28,7 @@
 
  private:
   ContentsView* contents_view_;
+  AppListView* const app_list_view_;  // Owned by the views hierarchy.
 
   DISALLOW_COPY_AND_ASSIGN(AllAppsTileItemView);
 };
diff --git a/ui/app_list/views/app_list_main_view.cc b/ui/app_list/views/app_list_main_view.cc
index f913e11..eb060ac0 100644
--- a/ui/app_list/views/app_list_main_view.cc
+++ b/ui/app_list/views/app_list_main_view.cc
@@ -44,11 +44,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 // AppListMainView:
 
-AppListMainView::AppListMainView(AppListViewDelegate* delegate)
+AppListMainView::AppListMainView(AppListViewDelegate* delegate,
+                                 AppListView* app_list_view)
     : delegate_(delegate),
       model_(delegate->GetModel()),
       search_box_view_(nullptr),
-      contents_view_(nullptr) {
+      contents_view_(nullptr),
+      app_list_view_(app_list_view) {
   SetLayoutManager(
       features::IsAnswerCardEnabled()
           ? static_cast<views::LayoutManager*>(new views::FillLayout)
@@ -77,8 +79,7 @@
 
 void AppListMainView::AddContentsViews() {
   DCHECK(search_box_view_);
-
-  contents_view_ = new ContentsView(this);
+  contents_view_ = new ContentsView(this, app_list_view_);
   contents_view_->Init(model_);
   AddChildView(contents_view_);
 
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h
index 937a5dd..7d06cab3 100644
--- a/ui/app_list/views/app_list_main_view.h
+++ b/ui/app_list/views/app_list_main_view.h
@@ -21,6 +21,7 @@
 
 class AppListItem;
 class AppListModel;
+class AppListView;
 class AppListViewDelegate;
 class ApplicationDragAndDropHost;
 class ContentsView;
@@ -35,7 +36,7 @@
                                         public SearchBoxViewDelegate,
                                         public SearchResultListViewDelegate {
  public:
-  explicit AppListMainView(AppListViewDelegate* delegate);
+  AppListMainView(AppListViewDelegate* delegate, AppListView* app_list_view);
   ~AppListMainView() override;
 
   void Init(gfx::NativeView parent,
@@ -99,6 +100,7 @@
   // Created by AppListView. Owned by views hierarchy.
   SearchBoxView* search_box_view_;
   ContentsView* contents_view_;  // Owned by views hierarchy.
+  AppListView* const app_list_view_;  // Owned by views hierarchy.
 
   DISALLOW_COPY_AND_ASSIGN(AppListMainView);
 };
diff --git a/ui/app_list/views/app_list_main_view_unittest.cc b/ui/app_list/views/app_list_main_view_unittest.cc
index 5cfa290..b365a44 100644
--- a/ui/app_list/views/app_list_main_view_unittest.cc
+++ b/ui/app_list/views/app_list_main_view_unittest.cc
@@ -82,10 +82,7 @@
     views::ViewsTestBase::SetUp();
     delegate_.reset(new AppListTestViewDelegate);
 
-    // In Ash, the third argument is a container aura::Window, but it is always
-    // NULL on Windows, and not needed for tests. It is only used to determine
-    // the scale factor for preloading icons.
-    main_view_ = new AppListMainView(delegate_.get());
+    main_view_ = new AppListMainView(delegate_.get(), nullptr);
     main_view_->SetPaintToLayer();
     main_view_->model()->SetFoldersEnabled(true);
     search_box_view_ = new SearchBoxView(main_view_, delegate_.get());
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc
index 060e7d7..a38c609 100644
--- a/ui/app_list/views/app_list_view.cc
+++ b/ui/app_list/views/app_list_view.cc
@@ -53,10 +53,33 @@
 namespace {
 
 // The margin from the edge to the speech UI.
-const int kSpeechUIMargin = 12;
+constexpr int kSpeechUIMargin = 12;
+
+// The height/width of the shelf.
+constexpr int kShelfSize = 48;
+
+// The height of the peeking app list.
+constexpr int kPeekingAppListHeight = 320;
+
+// The fraction of app list height that the app list must be released at in
+// order to transition to the next state.
+constexpr int kAppListThresholdDenominator = 3;
+
+// The velocity the app list must be dragged in order to transition to the next
+// state, measured in DIPs/event.
+constexpr int kAppListDragVelocityThreshold = 25;
+
+// The opacity of the app list background.
+constexpr float kAppListOpacity = 0.8;
 
 // The vertical position for the appearing animation of the speech UI.
-const float kSpeechUIAppearingPosition = 12;
+constexpr float kSpeechUIAppearingPosition = 12;
+
+bool IsFullscreenAppListEnabled() {
+  // Cache this value to avoid repeated lookup.
+  static bool cached_value = features::IsFullscreenAppListEnabled();
+  return cached_value;
+}
 
 // This view forwards the focus to the search box widget by providing it as a
 // FocusTraversable when a focus search is provided.
@@ -174,11 +197,16 @@
       search_box_focus_host_(nullptr),
       search_box_widget_(nullptr),
       search_box_view_(nullptr),
+      app_list_state_(PEEKING),
+      display_observer_(this),
       overlay_view_(nullptr),
       animation_observer_(new HideViewAnimationObserver()) {
   CHECK(delegate);
 
   delegate_->GetSpeechUI()->AddObserver(this);
+
+  if (IsFullscreenAppListEnabled())
+    display_observer_.Add(display::Screen::GetScreen());
 }
 
 AppListView::~AppListView() {
@@ -195,15 +223,20 @@
   set_color(kContentsBackgroundColor);
   set_parent_window(parent);
 
-  if (features::IsFullscreenAppListEnabled())
+  if (IsFullscreenAppListEnabled())
     InitializeFullscreen(parent, initial_apps_page);
   else
     InitializeBubble(parent, initial_apps_page);
 
   InitChildWidgets();
   AddChildView(overlay_view_);
+
+  if (IsFullscreenAppListEnabled())
+    SetState(app_list_state_);
+
   if (delegate_)
     delegate_->ViewInitialized();
+
   UMA_HISTOGRAM_TIMES("Apps.AppListCreationTime",
                       base::Time::Now() - start_time);
 }
@@ -216,7 +249,7 @@
 
 void AppListView::MaybeSetAnchorPoint(const gfx::Point& anchor_point) {
   // if the AppListView is a bubble
-  if (!features::IsFullscreenAppListEnabled())
+  if (!IsFullscreenAppListEnabled())
     SetAnchorRect(gfx::Rect(anchor_point, gfx::Size()));
 }
 
@@ -229,14 +262,9 @@
   app_list_main_view_->ShowAppListWhenReady();
 }
 
-void AppListView::CloseAppList() {
-  app_list_main_view_->Close();
-  delegate_->Dismiss();
-}
-
 void AppListView::UpdateBounds() {
   // if the AppListView is a bubble
-  if (!features::IsFullscreenAppListEnabled())
+  if (!IsFullscreenAppListEnabled())
     SizeToContents();
 }
 
@@ -329,14 +357,23 @@
       FROM_HERE_WITH_EXPLICIT_FUNCTION(
           "440224, 441028 AppListView::InitContents"));
 
-  app_list_main_view_ = new AppListMainView(delegate_);
+  if (IsFullscreenAppListEnabled()) {
+    // The shield view that colors the background of the app list and makes it
+    // transparent.
+    app_list_background_shield_ = new views::View;
+    app_list_background_shield_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
+    app_list_background_shield_->layer()->SetColor(SK_ColorBLACK);
+    app_list_background_shield_->layer()->SetOpacity(kAppListOpacity);
+    AddChildView(app_list_background_shield_);
+  }
+  app_list_main_view_ = new AppListMainView(delegate_, this);
   AddChildView(app_list_main_view_);
   app_list_main_view_->SetPaintToLayer();
   app_list_main_view_->layer()->SetFillsBoundsOpaquely(false);
   app_list_main_view_->layer()->SetMasksToBounds(true);
   // This will be added to the |search_box_widget_| after the app list widget is
   // initialized.
-  search_box_view_ = new SearchBoxView(app_list_main_view_, delegate_);
+  search_box_view_ = new SearchBoxView(app_list_main_view_, delegate_, this);
   search_box_view_->SetPaintToLayer();
   search_box_view_->layer()->SetFillsBoundsOpaquely(false);
   search_box_view_->layer()->SetMasksToBounds(true);
@@ -403,19 +440,29 @@
 
 void AppListView::InitializeFullscreen(gfx::NativeView parent,
                                        int initial_apps_page) {
-  views::Widget* widget = new views::Widget;
+  gfx::Rect display_work_area_bounds =
+      display::Screen::GetScreen()
+          ->GetDisplayNearestView(parent_window())
+          .work_area();
+
+  gfx::Rect app_list_overlay_view_bounds(
+      display_work_area_bounds.x(),
+      display_work_area_bounds.height() + kShelfSize - kPeekingAppListHeight,
+      display_work_area_bounds.width(),
+      display_work_area_bounds.height() + kShelfSize);
+
+  fullscreen_widget_ = new views::Widget;
   views::Widget::InitParams app_list_overlay_view_params(
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
 
+  app_list_overlay_view_params.name = "AppList";
   app_list_overlay_view_params.parent = parent;
   app_list_overlay_view_params.delegate = this;
   app_list_overlay_view_params.opacity =
       views::Widget::InitParams::TRANSLUCENT_WINDOW;
-  app_list_overlay_view_params.bounds =
-      display::Screen::GetScreen()->
-      GetDisplayNearestView(parent).work_area();
-  widget->Init(app_list_overlay_view_params);
-  widget->GetLayer()->SetBackgroundBlur(10);
+  app_list_overlay_view_params.bounds = app_list_overlay_view_bounds;
+  app_list_overlay_view_params.layer_type = ui::LAYER_SOLID_COLOR;
+  fullscreen_widget_->Init(app_list_overlay_view_params);
 
   overlay_view_ = new AppListOverlayView(0 /* no corners */);
 }
@@ -426,8 +473,8 @@
   set_close_on_deactivate(false);
   set_shadow(views::BubbleBorder::NO_ASSETS);
 
-  // This creates the app list widget. (Before this, child widgets cannot be
-  // created.)
+  // This creates the app list widget (Before this, child widgets cannot be
+  // created).
   views::BubbleDialogDelegateView::CreateBubble(this);
 
   SetBubbleArrow(views::BubbleBorder::FLOAT);
@@ -442,6 +489,79 @@
   overlay_view_->SetBoundsRect(GetContentsBounds());
 }
 
+void AppListView::StartDrag(const gfx::Point& location) {
+  initial_drag_point_ = location;
+}
+
+void AppListView::UpdateDrag(const gfx::Point& location) {
+  // Update the bounds of the widget while maintaining the
+  // relative position of the top of the widget and the mouse/gesture.
+  // Block drags north of 0 and recalculate the initial_drag_point_.
+  int const new_y_position = location.y() - initial_drag_point_.y() +
+                             fullscreen_widget_->GetWindowBoundsInScreen().y();
+  gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen();
+  if (new_y_position < 0) {
+    new_widget_bounds.set_y(0);
+    initial_drag_point_ = location;
+  } else {
+    new_widget_bounds.set_y(new_y_position);
+  }
+  fullscreen_widget_->SetBounds(new_widget_bounds);
+}
+
+void AppListView::EndDrag(const gfx::Point& location) {
+  // Change the app list state based on where the drag ended. If fling velocity
+  // was over the threshold, snap to the next state in the direction of the
+  // fling.
+  int const new_y_position = location.y() - initial_drag_point_.y() +
+                             fullscreen_widget_->GetWindowBoundsInScreen().y();
+  if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) {
+    // If the user releases drag with velocity over the threshold, snap to
+    // the next state, ignoring the drag release position.
+    if (app_list_state_ == FULLSCREEN) {
+      if (last_fling_velocity_ > 0)
+        SetState(PEEKING);
+
+    } else {
+      SetState(last_fling_velocity_ > 0 ? CLOSED : FULLSCREEN);
+    }
+    last_fling_velocity_ = 0;
+  } else {
+    int display_height = display::Screen::GetScreen()
+                             ->GetDisplayNearestView(parent_window())
+                             .work_area()
+                             .height();
+    int default_peeking_y = display_height + kShelfSize - kPeekingAppListHeight;
+    // The drag release velocity was too low, so use the release point.
+    int app_list_snap_y =
+        (app_list_state_ == FULLSCREEN) ? 0 : default_peeking_y;
+    // The DIP delta that must be exceeded for the app list to snap to the next
+    // state.
+    int app_list_threshold =
+        (fullscreen_widget_->GetWindowBoundsInScreen().height() + kShelfSize) /
+        kAppListThresholdDenominator;
+    app_list_threshold -=
+        (app_list_state_ == FULLSCREEN ? 0 : kPeekingAppListHeight) /
+        kAppListThresholdDenominator;
+
+    // If the user releases +/- 1/3 of |app_list_threshold|, snap to the
+    // next state.
+    if (std::abs(app_list_snap_y - new_y_position) < app_list_threshold) {
+      // The drag was not far enough so set the app list bounds to the target
+      // bounds for the current state.
+      SetState(app_list_state_);
+    } else if ((app_list_snap_y + app_list_threshold) < new_y_position) {
+      // The drag was far enough to change states and was a downward drag, so
+      // set the app list bounds to the next state.
+      SetState(app_list_state_ == FULLSCREEN ? PEEKING : CLOSED);
+    } else {
+      // The drag was far enough to change states and was an upward drag, so
+      // set the app list bounds to the next state.
+      SetState(FULLSCREEN);
+    }
+  }
+}
+
 void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params,
                                            views::Widget* widget) const {
   if (!params->native_widget) {
@@ -475,14 +595,64 @@
   mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds()));
 }
 
+void AppListView::OnMouseEvent(ui::MouseEvent* event) {
+  if (!IsFullscreenAppListEnabled())
+    return;
+
+  switch (event->type()) {
+    case ui::ET_MOUSE_PRESSED:
+      StartDrag(event->location());
+      event->SetHandled();
+      break;
+    case ui::ET_MOUSE_DRAGGED:
+      UpdateDrag(event->location());
+      event->SetHandled();
+      break;
+    case ui::ET_MOUSE_RELEASED:
+      EndDrag(event->location());
+      event->SetHandled();
+      break;
+    default:
+      break;
+  }
+}
+
+void AppListView::OnGestureEvent(ui::GestureEvent* event) {
+  if (!IsFullscreenAppListEnabled())
+    return;
+
+  switch (event->type()) {
+    case ui::ET_GESTURE_SCROLL_BEGIN:
+      StartDrag(event->location());
+      event->SetHandled();
+      break;
+    case ui::ET_GESTURE_SCROLL_UPDATE:
+      last_fling_velocity_ = event->details().velocity_y();
+      UpdateDrag(event->location());
+      event->SetHandled();
+      break;
+    case ui::ET_GESTURE_END:
+      EndDrag(event->location());
+      event->SetHandled();
+      break;
+    default:
+      break;
+  }
+}
+
 bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) {
   DCHECK_EQ(ui::VKEY_ESCAPE, accelerator.key_code());
 
   // If the ContentsView does not handle the back action, then this is the
   // top level, so we close the app list.
   if (!app_list_main_view_->contents_view()->Back()) {
+    if (IsFullscreenAppListEnabled()) {
+      SetState(CLOSED);
+    } else {
+      app_list_main_view_->Close();
+      delegate_->Dismiss();
+    }
     GetWidget()->Deactivate();
-    CloseAppList();
   }
 
   // Don't let DialogClientView handle the accelerator.
@@ -510,6 +680,11 @@
     speech_bounds.Inset(-speech_view_->GetInsets());
     speech_view_->SetBoundsRect(speech_bounds);
   }
+
+  if (IsFullscreenAppListEnabled()) {
+    app_list_main_view_->contents_view()->Layout();
+    app_list_background_shield_->SetBoundsRect(contents_bounds);
+  }
 }
 
 void AppListView::SchedulePaintInRect(const gfx::Rect& rect) {
@@ -518,6 +693,31 @@
     GetBubbleFrameView()->SchedulePaint();
 }
 
+void AppListView::SetState(AppListState new_state) {
+  gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen();
+  switch (new_state) {
+    case PEEKING: {
+      int display_height = display::Screen::GetScreen()
+                               ->GetDisplayNearestView(parent_window())
+                               .work_area()
+                               .bottom();
+      int default_peeking_y =
+          display_height + kShelfSize - kPeekingAppListHeight;
+      new_widget_bounds.set_y(default_peeking_y);
+      break;
+    }
+    case FULLSCREEN:
+      new_widget_bounds.set_y(0);
+      break;
+    case CLOSED:
+      app_list_main_view_->Close();
+      delegate_->Dismiss();
+      break;
+  }
+  fullscreen_widget_->SetBounds(new_widget_bounds);
+  app_list_state_ = new_state;
+}
+
 void AppListView::OnWidgetDestroying(views::Widget* widget) {
   BubbleDialogDelegateView::OnWidgetDestroying(widget);
   if (delegate_ && widget == GetWidget())
@@ -602,4 +802,21 @@
   }
 }
 
+void AppListView::OnDisplayMetricsChanged(const display::Display& display,
+                                          uint32_t changed_metrics) {
+  if (!IsFullscreenAppListEnabled())
+    return;
+
+  // Set the |fullscreen_widget_| size to fit the new display metrics.
+  gfx::Size size = display::Screen::GetScreen()
+                       ->GetDisplayNearestView(parent_window())
+                       .work_area()
+                       .size();
+  size.Enlarge(0, kShelfSize);
+  fullscreen_widget_->SetSize(size);
+
+  // Update the |fullscreen_widget_| bounds to accomodate the new work area.
+  SetState(app_list_state_);
+}
+
 }  // namespace app_list
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h
index 3b657141..84b0ead 100644
--- a/ui/app_list/views/app_list_view.h
+++ b/ui/app_list/views/app_list_view.h
@@ -9,12 +9,18 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
+#include "base/scoped_observer.h"
 #include "build/build_config.h"
 #include "ui/app_list/app_list_export.h"
 #include "ui/app_list/speech_ui_model_observer.h"
+#include "ui/display/display_observer.h"
 #include "ui/views/bubble/bubble_dialog_delegate.h"
 #include "ui/views/widget/widget.h"
 
+namespace display {
+class Screen;
+}
+
 namespace app_list {
 class ApplicationDragAndDropHost;
 class AppListMainView;
@@ -32,15 +38,28 @@
 // AppListView is the top-level view and controller of app list UI. It creates
 // and hosts a AppsGridView and passes AppListModel to it for display.
 class APP_LIST_EXPORT AppListView : public views::BubbleDialogDelegateView,
-                                    public SpeechUIModelObserver {
+                                    public SpeechUIModelObserver,
+                                    public display::DisplayObserver {
  public:
+  enum AppListState {
+    // If set, closes |app_list_main_view_| and dismisses the delegate.
+    CLOSED = 0,
+
+    // The initial state for the app list. If set, the widget will peek over
+    // the shelf by kPeekingAppListHeight DIPs.
+    PEEKING,
+
+    // If set, the widget will be repositioned to take up the whole screen.
+    FULLSCREEN,
+  };
+
   // Does not take ownership of |delegate|.
   explicit AppListView(AppListViewDelegate* delegate);
   ~AppListView() override;
 
-  // Initializes the widget as a bubble or fullscreen view depending on the
-  // presence of a cmd line switch. parent and initial_apps_page are used for
-  // both the bubble and fullscreen initialization.
+  // Initializes the widget as a bubble or fullscreen view depending on if the
+  // fullscreen app list feature is set. |parent| and |initial_apps_page| are
+  // used for both the bubble and fullscreen initialization.
   void Initialize(gfx::NativeView parent, int initial_apps_page);
 
   void SetBubbleArrow(views::BubbleBorder::Arrow arrow);
@@ -58,8 +77,6 @@
   // timer to show the UI when a maximum allowed wait time has expired.
   void ShowWhenReady();
 
-  void CloseAppList();
-
   void UpdateBounds();
 
   // Enables/disables a semi-transparent overlay over the app list (good for
@@ -89,6 +106,12 @@
   void Layout() override;
   void SchedulePaintInRect(const gfx::Rect& rect) override;
 
+  // Changes the app list state.
+  void SetState(AppListState new_state);
+
+  bool is_fullscreen() const { return app_list_state_ == FULLSCREEN; }
+  AppListState app_list_state() const { return app_list_state_; }
+
  private:
   friend class test::AppListViewTestApi;
 
@@ -102,6 +125,17 @@
   // Initializes the widget as a bubble.
   void InitializeBubble(gfx::NativeView parent, int initial_apps_page);
 
+  // Initializes |initial_drag_point_|.
+  void StartDrag(const gfx::Point& location);
+
+  // Updates the bounds of the widget while maintaining the relative position
+  // of the top of the widget and the gesture.
+  void UpdateDrag(const gfx::Point& location);
+
+  // Handles app list state transfers. If the drag was fast enough, ignore the
+  // release position and snap to the next state.
+  void EndDrag(const gfx::Point& location);
+
   // Overridden from views::BubbleDialogDelegateView:
   void OnBeforeBubbleWidgetInit(views::Widget::InitParams* params,
                                 views::Widget* widget) const override;
@@ -112,6 +146,10 @@
   bool WidgetHasHitTestMask() const override;
   void GetWidgetHitTestMask(gfx::Path* mask) const override;
 
+  // Overridden from ui::EventHandler:
+  void OnMouseEvent(ui::MouseEvent* event) override;
+  void OnGestureEvent(ui::GestureEvent* event) override;
+
   // Overridden from views::WidgetObserver:
   void OnWidgetDestroying(views::Widget* widget) override;
   void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override;
@@ -120,14 +158,31 @@
   void OnSpeechRecognitionStateChanged(
       SpeechRecognitionState new_state) override;
 
+  // Overridden from DisplayObserver:
+  void OnDisplayMetricsChanged(const display::Display& display,
+                               uint32_t changed_metrics) override;
+
   AppListViewDelegate* delegate_;  // Weak. Owned by AppListService.
 
   AppListMainView* app_list_main_view_;
   SpeechView* speech_view_;
+  views::Widget* fullscreen_widget_ = nullptr;  // Owned by AppListView.
 
   views::View* search_box_focus_host_;  // Owned by the views hierarchy.
   views::Widget* search_box_widget_;    // Owned by the app list's widget.
   SearchBoxView* search_box_view_;      // Owned by |search_box_widget_|.
+  // Owned by the app list's widget. Null if the fullscreen app list is not
+  // enabled.
+  views::View* app_list_background_shield_ = nullptr;
+  // The gap between the initial gesture event and the top of the window.
+  gfx::Point initial_drag_point_;
+  // The velocity of the gesture event.
+  float last_fling_velocity_ = 0;
+  // The state of the app list, controlled via SetState().
+  AppListState app_list_state_;
+
+  // An observer that notifies AppListView when the display has changed.
+  ScopedObserver<display::Screen, display::DisplayObserver> display_observer_;
 
   // A semi-transparent white overlay that covers the app list while dialogs are
   // open.
diff --git a/ui/app_list/views/contents_view.cc b/ui/app_list/views/contents_view.cc
index 9a3a73b7..ff96d24 100644
--- a/ui/app_list/views/contents_view.cc
+++ b/ui/app_list/views/contents_view.cc
@@ -29,13 +29,15 @@
 
 namespace app_list {
 
-ContentsView::ContentsView(AppListMainView* app_list_main_view)
+ContentsView::ContentsView(AppListMainView* app_list_main_view,
+                           AppListView* app_list_view)
     : model_(nullptr),
       apps_container_view_(nullptr),
       search_results_page_view_(nullptr),
       start_page_view_(nullptr),
       custom_page_view_(nullptr),
       app_list_main_view_(app_list_main_view),
+      app_list_view_(app_list_view),
       page_before_search_(0) {
   pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs,
                                            kOverscrollPageTransitionDurationMs);
@@ -64,7 +66,8 @@
   }
 
   // Start page.
-  start_page_view_ = new StartPageView(app_list_main_view_, view_delegate);
+  start_page_view_ =
+      new StartPageView(app_list_main_view_, view_delegate, app_list_view_);
   AddLauncherPage(start_page_view_, AppListModel::STATE_START);
 
   // Search results UI.
diff --git a/ui/app_list/views/contents_view.h b/ui/app_list/views/contents_view.h
index 62a52cd2..a27300fe 100644
--- a/ui/app_list/views/contents_view.h
+++ b/ui/app_list/views/contents_view.h
@@ -26,6 +26,7 @@
 
 class AppsGridView;
 class AppListPage;
+class AppListView;
 class ApplicationDragAndDropHost;
 class AppListFolderItem;
 class AppListMainView;
@@ -44,7 +45,7 @@
 class APP_LIST_EXPORT ContentsView : public views::View,
                                      public PaginationModelObserver {
  public:
-  explicit ContentsView(AppListMainView* app_list_main_view);
+  ContentsView(AppListMainView* app_list_main_view, AppListView* app_list_view);
   ~ContentsView() override;
 
   // Initialize the pages of the launcher. Should be called after
@@ -191,6 +192,9 @@
   // Parent view. Owned by the views hierarchy.
   AppListMainView* app_list_main_view_;
 
+  // Owned by the views hierarchy.
+  AppListView* const app_list_view_;
+
   // Maps State onto |view_model_| indices.
   std::map<AppListModel::State, int> state_to_view_;
 
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc
index 0d8aec2..599f298e8 100644
--- a/ui/app_list/views/search_box_view.cc
+++ b/ui/app_list/views/search_box_view.cc
@@ -10,12 +10,14 @@
 #include "base/memory/ptr_util.h"
 #include "build/build_config.h"
 #include "ui/app_list/app_list_constants.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/app_list/app_list_model.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/resources/grit/app_list_resources.h"
 #include "ui/app_list/search_box_model.h"
 #include "ui/app_list/speech_ui_model.h"
+#include "ui/app_list/views/app_list_view.h"
 #include "ui/app_list/views/contents_view.h"
 #include "ui/app_list/views/search_box_view_delegate.h"
 #include "ui/base/ime/text_input_flags.h"
@@ -34,6 +36,7 @@
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/layout/fill_layout.h"
 #include "ui/views/shadow_border.h"
+#include "ui/views/widget/widget.h"
 
 namespace app_list {
 
@@ -42,16 +45,28 @@
 const int kPadding = 16;
 const int kInnerPadding = 24;
 const int kPreferredWidth = 360;
+const int kPreferredWidthFullscreen = 544;
 const int kPreferredHeight = 48;
 
 const SkColor kHintTextColor = SkColorSetRGB(0xA0, 0xA0, 0xA0);
 
 const int kBackgroundBorderCornerRadius = 2;
+const int kBackgroundBorderCornerRadiusFullscreen = 20;
+
+bool IsFullscreenAppListEnabled() {
+  // Cache this value to avoid repeated lookup.
+  static bool cached_value = features::IsFullscreenAppListEnabled();
+  return cached_value;
+}
 
 // A background that paints a solid white rounded rect with a thin grey border.
 class SearchBoxBackground : public views::Background {
  public:
-  SearchBoxBackground() {}
+  SearchBoxBackground()
+      : background_border_corner_radius_(
+            IsFullscreenAppListEnabled()
+                ? kBackgroundBorderCornerRadiusFullscreen
+                : kBackgroundBorderCornerRadius) {}
   ~SearchBoxBackground() override {}
 
  private:
@@ -62,9 +77,11 @@
     cc::PaintFlags flags;
     flags.setAntiAlias(true);
     flags.setColor(kSearchBoxBackground);
-    canvas->DrawRoundRect(bounds, kBackgroundBorderCornerRadius, flags);
+    canvas->DrawRoundRect(bounds, background_border_corner_radius_, flags);
   }
 
+  const int background_border_corner_radius_;
+
   DISALLOW_COPY_AND_ASSIGN(SearchBoxBackground);
 };
 
@@ -114,7 +131,8 @@
 };
 
 SearchBoxView::SearchBoxView(SearchBoxViewDelegate* delegate,
-                             AppListViewDelegate* view_delegate)
+                             AppListViewDelegate* view_delegate,
+                             AppListView* app_list_view)
     : delegate_(delegate),
       view_delegate_(view_delegate),
       model_(NULL),
@@ -123,9 +141,13 @@
       speech_button_(NULL),
       search_box_(new views::Textfield),
       contents_view_(NULL),
+      app_list_view_(app_list_view),
       focused_view_(FOCUS_SEARCH_BOX) {
   SetLayoutManager(new views::FillLayout);
-  SetPreferredSize(gfx::Size(kPreferredWidth, kPreferredHeight));
+  SetPreferredSize(gfx::Size(IsFullscreenAppListEnabled()
+                                 ? kPreferredWidthFullscreen
+                                 : kPreferredWidth,
+                             kPreferredHeight));
   AddChildView(content_container_);
 
   SetShadow(GetShadowForZHeight(2));
@@ -323,6 +345,11 @@
   UpdateModel();
   view_delegate_->AutoLaunchCanceled();
   NotifyQueryChanged();
+
+  if (IsFullscreenAppListEnabled() && !app_list_view_->is_fullscreen()) {
+    // If the app list is in the peeking state, switch it to fullscreen.
+    app_list_view_->SetState(AppListView::FULLSCREEN);
+  }
 }
 
 bool SearchBoxView::HandleKeyEvent(views::Textfield* sender,
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h
index 8b5790bc..db647e9 100644
--- a/ui/app_list/views/search_box_view.h
+++ b/ui/app_list/views/search_box_view.h
@@ -31,6 +31,7 @@
 };
 
 class AppListModel;
+class AppListView;
 class AppListViewDelegate;
 class SearchBoxModel;
 class SearchBoxViewDelegate;
@@ -47,7 +48,8 @@
                                       public SpeechUIModelObserver {
  public:
   SearchBoxView(SearchBoxViewDelegate* delegate,
-                AppListViewDelegate* view_delegate);
+                AppListViewDelegate* view_delegate,
+                AppListView* app_list_view = nullptr);
   ~SearchBoxView() override;
 
   void ModelChanged();
@@ -118,6 +120,7 @@
   SearchBoxImageButton* speech_button_;  // Owned by views hierarchy.
   views::Textfield* search_box_;  // Owned by views hierarchy.
   views::View* contents_view_;  // Owned by views hierarchy.
+  app_list::AppListView* app_list_view_;  // Owned by views hierarchy.
 
   SearchBoxFocus focused_view_;  // Which element has TAB'd focus.
 
diff --git a/ui/app_list/views/start_page_view.cc b/ui/app_list/views/start_page_view.cc
index 27dce46..c9166f3 100644
--- a/ui/app_list/views/start_page_view.cc
+++ b/ui/app_list/views/start_page_view.cc
@@ -13,8 +13,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/app_list/app_list_constants.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_model.h"
+#include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/search_result.h"
 #include "ui/app_list/views/all_apps_tile_item_view.h"
@@ -52,6 +54,7 @@
 constexpr int kTileSpacing = 7;
 constexpr int kNumStartPageTilesCols = 5;
 constexpr int kTilesHorizontalMarginLeft = 145;
+constexpr int kCenterColumnOfStartPageAppGrid = 3;
 
 constexpr int kLauncherPageBackgroundWidth = 400;
 
@@ -137,7 +140,10 @@
   SetBackground(views::CreateSolidBackground(kLabelBackgroundColor));
   all_apps_button_->SetHoverStyle(TileItemView::HOVER_STYLE_ANIMATE_SHADOW);
   all_apps_button_->SetParentBackgroundColor(kLabelBackgroundColor);
-  CreateAppsGrid(kNumStartPageTiles);
+
+  CreateAppsGrid(features::IsFullscreenAppListEnabled()
+                     ? kNumStartPageTilesFullscreen
+                     : kNumStartPageTiles);
 }
 
 StartPageView::StartPageTilesContainer::~StartPageTilesContainer() {
@@ -171,7 +177,10 @@
       delete search_result_tile_views_[i];
     search_result_tile_views_.clear();
     RemoveChildView(all_apps_button_);
-    CreateAppsGrid(std::min(kNumStartPageTiles, display_results.size()));
+
+    CreateAppsGrid(features::IsFullscreenAppListEnabled()
+                       ? kNumStartPageTilesFullscreen
+                       : std::min(kNumStartPageTiles, display_results.size()));
   }
 
   // Update the tile item results.
@@ -242,10 +251,19 @@
     search_result_tile_views_.emplace_back(tile_item);
   }
 
-  // Also add a special "all apps" button to the end of the container.
   all_apps_button_->UpdateIcon();
-  if (i % kNumStartPageTilesCols == 0)
+  if (features::IsFullscreenAppListEnabled()) {
+    // Also add a special "all apps" button to the middle of the next row of the
+    // container.
     tiles_layout_manager->StartRow(0, 0);
+    tiles_layout_manager->SkipColumns(kCenterColumnOfStartPageAppGrid);
+  } else {
+    // Also add a special "all apps" button to the end of the next row of the
+    // container.
+    if (i % kNumStartPageTilesCols == 0)
+      tiles_layout_manager->StartRow(0, 0);
+  }
+
   tiles_layout_manager->AddView(all_apps_button_);
   AddChildView(all_apps_button_);
 }
@@ -253,7 +271,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // StartPageView implementation:
 StartPageView::StartPageView(AppListMainView* app_list_main_view,
-                             AppListViewDelegate* view_delegate)
+                             AppListViewDelegate* view_delegate,
+                             AppListView* app_list_view)
     : app_list_main_view_(app_list_main_view),
       view_delegate_(view_delegate),
       search_box_spacer_view_(new View()),
@@ -262,7 +281,8 @@
           view_delegate_->GetModel()->custom_launcher_page_name())),
       tiles_container_(new StartPageTilesContainer(
           app_list_main_view->contents_view(),
-          new AllAppsTileItemView(app_list_main_view_->contents_view()),
+          new AllAppsTileItemView(app_list_main_view_->contents_view(),
+                                  app_list_view),
           view_delegate)) {
   search_box_spacer_view_->SetPreferredSize(gfx::Size(
       kStartPageSearchBoxWidth,
@@ -274,7 +294,6 @@
 
   // The view containing the start page tiles.
   AddChildView(tiles_container_);
-
   AddChildView(custom_launcher_page_background_);
 
   tiles_container_->SetResults(view_delegate_->GetModel()->results());
@@ -294,11 +313,16 @@
       views::BoxLayout::CROSS_AXIS_ALIGNMENT_CENTER);
   instant_container_->SetLayoutManager(instant_layout_manager);
 
-  views::View* web_view = view_delegate_->CreateStartPageWebView(
-      gfx::Size(kWebViewWidth, kWebViewHeight));
-  if (web_view) {
-    web_view->SetFocusBehavior(FocusBehavior::NEVER);
-    instant_container_->AddChildView(web_view);
+  // Create the view for the Google Doodle if the fullscreen launcher is not
+  // enabled.
+  if (!features::IsFullscreenAppListEnabled()) {
+    views::View* web_view = view_delegate_->CreateStartPageWebView(
+        gfx::Size(kWebViewWidth, kWebViewHeight));
+
+    if (web_view) {
+      web_view->SetFocusBehavior(FocusBehavior::NEVER);
+      instant_container_->AddChildView(web_view);
+    }
   }
 
   instant_container_->AddChildView(search_box_spacer_view_);
diff --git a/ui/app_list/views/start_page_view.h b/ui/app_list/views/start_page_view.h
index 28f9c2e..ef68aa0d 100644
--- a/ui/app_list/views/start_page_view.h
+++ b/ui/app_list/views/start_page_view.h
@@ -16,6 +16,7 @@
 namespace app_list {
 
 class AppListMainView;
+class AppListView;
 class AppListViewDelegate;
 class CustomLauncherPageBackgroundView;
 class SearchResultTileItemView;
@@ -25,7 +26,8 @@
 class APP_LIST_EXPORT StartPageView : public AppListPage {
  public:
   StartPageView(AppListMainView* app_list_main_view,
-                AppListViewDelegate* view_delegate);
+                AppListViewDelegate* view_delegate,
+                AppListView* app_list_view);
   ~StartPageView() override;
 
   void Reset();
@@ -50,11 +52,11 @@
   void OnGestureEvent(ui::GestureEvent* event) override;
   void OnScrollEvent(ui::ScrollEvent* event) override;
 
-
  private:
   class StartPageTilesContainer;
 
   void InitInstantContainer();
+
   void MaybeOpenCustomLauncherPage();
 
   void SetCustomLauncherPageSelected(bool selected);
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index e0b23166f..325e13f 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -233,15 +233,17 @@
           base::MakeUnique<cc::DelayBasedTimeSource>(
               compositor->task_runner().get())));
   std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
-      compositor->task_runner().get(),
+      begin_frame_source.get(), compositor->task_runner().get(),
       display_output_surface->capabilities().max_frames_pending));
 
   data->display = base::MakeUnique<cc::Display>(
       &shared_bitmap_manager_, &gpu_memory_buffer_manager_, renderer_settings_,
-      compositor->frame_sink_id(), begin_frame_source.get(),
-      std::move(display_output_surface), std::move(scheduler),
+      compositor->frame_sink_id(), std::move(display_output_surface),
+      std::move(scheduler),
       base::MakeUnique<cc::TextureMailboxDeleter>(
           compositor->task_runner().get()));
+  GetSurfaceManager()->RegisterBeginFrameSource(begin_frame_source.get(),
+                                                compositor->frame_sink_id());
   // Note that we are careful not to destroy a prior |data->begin_frame_source|
   // until we have reset |data->display|.
   data->begin_frame_source = std::move(begin_frame_source);
@@ -286,6 +288,8 @@
   if (it == per_compositor_data_.end())
     return;
   PerCompositorData* data = it->second.get();
+  GetSurfaceManager()->UnregisterBeginFrameSource(
+      data->begin_frame_source.get());
   DCHECK(data);
 #if !defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
   if (data->surface_handle)
diff --git a/ui/gfx/vector_icon_types.h b/ui/gfx/vector_icon_types.h
index 36eb18eb..facc054 100644
--- a/ui/gfx/vector_icon_types.h
+++ b/ui/gfx/vector_icon_types.h
@@ -13,8 +13,6 @@
 
 namespace gfx {
 
-enum class VectorIconId;
-
 // The size of a single side of the square canvas to which path coordinates
 // are relative, in device independent pixels.
 const int kReferenceSizeDip = 48;
@@ -87,13 +85,6 @@
   const gfx::PathElement* path_1x;
 };
 
-// Returns an array of path commands and arguments, terminated by END.
-const PathElement* GetPathForVectorIcon(VectorIconId id);
-// As above, but returns an icon specifically adjusted for 1x scale factors.
-// This draws from icon files that end with .1x.icon. If no such file exists,
-// it will fall back to GetPathForVectorIcon.
-const PathElement* GetPathForVectorIconAt1xScale(VectorIconId id);
-
 }  // namespace gfx
 
 #endif  // UI_GFX_VECTOR_ICON_TYPES_H_
diff --git a/ui/vector_icons/aggregate_vector_icons.py b/ui/vector_icons/aggregate_vector_icons.py
index bf46ffd..87aa1be 100644
--- a/ui/vector_icons/aggregate_vector_icons.py
+++ b/ui/vector_icons/aggregate_vector_icons.py
@@ -10,58 +10,6 @@
 import sys
 import textwrap
 
-def AggregateVectorIconsLegacy(working_directory, file_list, output_cc,
-                               output_h):
-  icon_list = []
-  assert file_list is not None
-  with open(file_list, 'r') as f:
-    file_list_contents = f.read()
-  icon_list = shlex.split(file_list_contents)
-
-  input_header_template = open(os.path.join(working_directory,
-                                            "vector_icons.h.template"))
-  header_template_contents = input_header_template.readlines()
-  input_header_template.close()
-  output_header = open(output_h, "w")
-  for line in header_template_contents:
-    if not "TEMPLATE_PLACEHOLDER" in line:
-      output_header.write(line)
-      continue
-
-    for icon_path in icon_list:
-      # The icon name should be of the format "foo.icon" or "foo.1x.icon".
-      (icon_name, extension) = os.path.splitext(os.path.basename(icon_path))
-      (icon_name, scale_factor) = os.path.splitext(icon_name)
-      if not scale_factor:
-        output_header.write("  {},\n".format(icon_name.upper()))
-  output_header.close()
-
-  input_cc_template = open(
-      os.path.join(working_directory, "vector_icons.cc.template"))
-  cc_template_contents = input_cc_template.readlines()
-  input_cc_template.close()
-  output_cc = open(output_cc, "w")
-  for line in cc_template_contents:
-    if not "TEMPLATE_PLACEHOLDER" in line:
-      output_cc.write(line)
-      continue;
-
-    for icon_path in icon_list:
-      (icon_name, extension) = os.path.splitext(os.path.basename(icon_path))
-      (icon_name, scale_factor) = os.path.splitext(icon_name)
-      assert not scale_factor or scale_factor == ".1x"
-      if (("1X" in line and scale_factor != ".1x") or
-          (not "1X" in line and scale_factor == ".1x")):
-        continue
-
-      icon_file = open(icon_path)
-      vector_commands = "".join(icon_file.readlines())
-      icon_file.close()
-      output_cc.write("ICON_TEMPLATE({}, {})\n".format(icon_name.upper(),
-                                                       vector_commands))
-  output_cc.close()
-
-
 def Error(msg):
   print >> sys.stderr, msg
   sys.exit(1)
@@ -73,28 +21,17 @@
   return 'k' + ''.join(words) + suffix
 
 
-def AggregateVectorIcons(working_directory, file_list, output_cc, output_h,
-                         use_legacy_template):
+def AggregateVectorIcons(working_directory, file_list, output_cc, output_h):
   """Compiles all .icon files in a directory into two C++ files.
 
   Args:
       working_directory: The path to the directory that holds the .icon files
           and C++ templates.
       file_list: A file containing the list of vector icon files to process.
-          Used for GN only (this argument defaults to None for GYP).
       output_cc: The path that should be used to write the .cc file.
       output_h: The path that should be used to write the .h file.
-      use_legacy_template: If True, |output_cc| and |output_h| are generated
-          using .template files which make use of the VectorIconId enum.
   """
 
-  # TODO(tdanderson): Remove this code once all vector icons map to VectorIcon
-  # constants rather than VectorIconId values.
-  if use_legacy_template:
-    AggregateVectorIconsLegacy(working_directory, file_list, output_cc,
-                               output_h)
-    return
-
   # For each file in |file_list|, place it in |path_map| if its extension is
   # .icon or place it in |path_map_1x| if its extension is .1x.icon. The
   # two dictionaries map the icon's name to its path, e.g.,
@@ -202,26 +139,18 @@
                          "icon files.")
   parser.add_option("--file_list",
                     help="A response file containing the list of icon files "
-                         "to be processed (GN only). Defaults to None.",
-                    default=None)
+                         "to be processed.")
   parser.add_option("--output_cc",
                     help="The path to output the CC file to.")
   parser.add_option("--output_h",
                     help="The path to output the header file to.")
-  parser.add_option("--use_legacy_template",
-                    action="store_true",
-                    help="When set, the VectorIconId enum is populated "
-                         "with values corresponding to .icon files in "
-                         "the current working directory.",
-                    default=False)
 
   (options, args) = parser.parse_args()
 
   AggregateVectorIcons(options.working_directory,
                        options.file_list,
                        options.output_cc,
-                       options.output_h,
-                       options.use_legacy_template)
+                       options.output_h)
 
 
 if __name__ == "__main__":
diff --git a/ui/views/animation/ink_drop_highlight_unittest.cc b/ui/views/animation/ink_drop_highlight_unittest.cc
index fa983da..f6acf85 100644
--- a/ui/views/animation/ink_drop_highlight_unittest.cc
+++ b/ui/views/animation/ink_drop_highlight_unittest.cc
@@ -11,6 +11,7 @@
 #include "base/time/time.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/gfx/animation/animation.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/views/animation/test/ink_drop_highlight_test_api.h"
 #include "ui/views/animation/test/test_ink_drop_highlight_observer.h"
@@ -95,6 +96,11 @@
 }
 
 TEST_F(InkDropHighlightTest, VerifyObserversAreNotified) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_highlight()->FadeIn(base::TimeDelta::FromSeconds(1));
 
   EXPECT_EQ(1, observer()->last_animation_started_ordinal());
@@ -139,6 +145,11 @@
 }
 
 TEST_F(InkDropHighlightTest, VerifyObserversAreNotifiedOfPreemptedAnimations) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_highlight()->FadeIn(base::TimeDelta::FromSeconds(1));
   ink_drop_highlight()->FadeOut(base::TimeDelta::FromSeconds(1),
                                 false /* explode */);
@@ -166,6 +177,11 @@
 // Verify animations are aborted during deletion and the
 // InkDropHighlightObservers are notified.
 TEST_F(InkDropHighlightTest, AnimationsAbortedDuringDeletion) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_highlight()->FadeIn(base::TimeDelta::FromSeconds(1));
   DestroyHighlight();
   EXPECT_EQ(1, observer()->last_animation_started_ordinal());
diff --git a/ui/views/animation/ink_drop_host_view_unittest.cc b/ui/views/animation/ink_drop_host_view_unittest.cc
index 50ac035..a6a7b002 100644
--- a/ui/views/animation/ink_drop_host_view_unittest.cc
+++ b/ui/views/animation/ink_drop_host_view_unittest.cc
@@ -10,6 +10,7 @@
 #include "ui/events/event_constants.h"
 #include "ui/events/event_handler.h"
 #include "ui/events/event_utils.h"
+#include "ui/gfx/animation/animation.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/size.h"
@@ -181,6 +182,11 @@
 }
 
 TEST_F(InkDropHostViewTest, DismissInkDropOnTouchOrGestureEvents) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   host_view_.SetSize(gfx::Size(20, 20));
 
   test_api_.SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER);
diff --git a/ui/views/animation/ink_drop_impl_unittest.cc b/ui/views/animation/ink_drop_impl_unittest.cc
index 2a9904e..27723b7 100644
--- a/ui/views/animation/ink_drop_impl_unittest.cc
+++ b/ui/views/animation/ink_drop_impl_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/gfx/animation/animation.h"
 #include "ui/views/animation/test/ink_drop_impl_test_api.h"
 #include "ui/views/animation/test/test_ink_drop_host.h"
 #include "ui/views/test/platform_test_helper.h"
@@ -205,6 +206,11 @@
 }
 
 TEST_F(InkDropImplTest, LayersRemovedFromHostAfterInkDrop) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   EXPECT_FALSE(AreLayersAddedToHost());
 
   ink_drop()->AnimateToState(InkDropState::ACTION_PENDING);
@@ -467,6 +473,11 @@
 }
 
 TEST_P(InkDropImplHideAutoHighlightTest, DeactivatedAnimatesWhenNotFocused) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   test_api()->SetShouldHighlight(false);
 
   ink_drop()->AnimateToState(InkDropState::ACTIVATED);
diff --git a/ui/views/animation/ink_drop_ripple_unittest.cc b/ui/views/animation/ink_drop_ripple_unittest.cc
index 1beb05b..26749495 100644
--- a/ui/views/animation/ink_drop_ripple_unittest.cc
+++ b/ui/views/animation/ink_drop_ripple_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/macros.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/animation/animation.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/views/animation/flood_fill_ink_drop_ripple.h"
@@ -175,6 +176,11 @@
 // Verify animations are aborted during deletion and the
 // InkDropRippleObservers are notified.
 TEST_P(InkDropRippleTest, AnimationsAbortedDuringDeletion) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
   ink_drop_ripple_.reset();
   EXPECT_EQ(1, observer_.last_animation_started_ordinal());
@@ -186,6 +192,11 @@
 }
 
 TEST_P(InkDropRippleTest, VerifyObserversAreNotified) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(InkDropState::ACTION_PENDING);
 
   EXPECT_TRUE(test_api_->HasActiveAnimations());
@@ -213,6 +224,11 @@
 }
 
 TEST_P(InkDropRippleTest, VerifyObserversAreNotifiedOfPreemptedAnimations) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(InkDropState::ACTION_PENDING);
   ink_drop_ripple_->AnimateToState(InkDropState::ALTERNATE_ACTION_PENDING);
 
@@ -252,6 +268,11 @@
 // Verifies all active animations are aborted and the InkDropState is set to
 // HIDDEN after invoking HideImmediately().
 TEST_P(InkDropRippleTest, HideImmediatelyWithActiveAnimations) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
   EXPECT_TRUE(test_api_->HasActiveAnimations());
   EXPECT_NE(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
@@ -297,6 +318,11 @@
 // Verifies all active animations are aborted and the InkDropState is set to
 // ACTIVATED after invoking SnapToActivated().
 TEST_P(InkDropRippleTest, SnapToActivatedWithActiveAnimations) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
   EXPECT_TRUE(test_api_->HasActiveAnimations());
   EXPECT_NE(InkDropState::ACTIVATED, ink_drop_ripple_->target_ink_drop_state());
@@ -327,6 +353,11 @@
 // the most recent value passed to AnimateToState() when notifying observers
 // that an animation has started within the AnimateToState() function call.
 TEST_P(InkDropRippleTest, TargetInkDropStateOnAnimationStarted) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
 
   EXPECT_TRUE(observer_.AnimationHasStarted());
@@ -345,6 +376,11 @@
 // the most recent value passed to AnimateToState() when notifying observers
 // that an animation has ended within the AnimateToState() function call.
 TEST_P(InkDropRippleTest, TargetInkDropStateOnAnimationEnded) {
+  // TODO(bruthig): Re-enable! For some reason these tests fail on some win
+  // trunk builds. See crbug.com/731811.
+  if (!gfx::Animation::ShouldRenderRichAnimation())
+    return;
+
   ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
 
   EXPECT_FALSE(observer_.AnimationHasEnded());
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc
index 9ec6b09..b5db556a 100644
--- a/ui/views/examples/dialog_example.cc
+++ b/ui/views/examples/dialog_example.cc
@@ -131,9 +131,9 @@
   const float kFixed = 0.f;
   const float kStretchy = 1.f;
 
+  views::LayoutProvider* provider = views::LayoutProvider::Get();
   const int horizontal_spacing =
-      views::LayoutProvider::Get()->GetDistanceMetric(
-          views::DISTANCE_RELATED_BUTTON_HORIZONTAL);
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_BUTTON_HORIZONTAL);
   GridLayout* layout = GridLayout::CreatePanel(container);
   container->SetLayoutManager(layout);
   ColumnSet* column_set = layout->AddColumnSet(kFieldsColumnId);
@@ -172,8 +172,9 @@
   column_set = layout->AddColumnSet(kButtonsColumnId);
   column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, kStretchy,
                         GridLayout::USE_PREF, 0, 0);
-  layout->StartRowWithPadding(kFixed, kButtonsColumnId, kFixed,
-                              kUnrelatedControlVerticalSpacing);
+  layout->StartRowWithPadding(
+      kFixed, kButtonsColumnId, kFixed,
+      provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
   show_ =
       MdTextButton::CreateSecondaryUiButton(this, base::ASCIIToUTF16("Show"));
   layout->AddView(show_);
diff --git a/ui/views/layout/layout_provider.cc b/ui/views/layout/layout_provider.cc
index 11412ca..a4fd678 100644
--- a/ui/views/layout/layout_provider.cc
+++ b/ui/views/layout/layout_provider.cc
@@ -94,6 +94,8 @@
       return kDialogMinimumButtonWidth;
     case DISTANCE_DIALOG_CONTENTS_HORIZONTAL_MARGIN:
       return kButtonHEdgeMarginNew;
+    case DISTANCE_UNRELATED_CONTROL_VERTICAL:
+      return kUnrelatedControlVerticalSpacing;
   }
   NOTREACHED();
   return 0;
diff --git a/ui/views/layout/layout_provider.h b/ui/views/layout/layout_provider.h
index 41da0c8..5d67084 100644
--- a/ui/views/layout/layout_provider.h
+++ b/ui/views/layout/layout_provider.h
@@ -78,6 +78,8 @@
   // The spacing between a pair of related vertical controls, used for
   // dialog layout.
   DISTANCE_RELATED_CONTROL_VERTICAL,
+  // Vertical spacing between controls that are logically unrelated.
+  DISTANCE_UNRELATED_CONTROL_VERTICAL,
 
   // Embedders must start DistanceMetric enum values from here.
   VIEWS_DISTANCE_END
diff --git a/ui/views/view_targeter_unittest.cc b/ui/views/view_targeter_unittest.cc
index d72a26a..1427abd4 100644
--- a/ui/views/view_targeter_unittest.cc
+++ b/ui/views/view_targeter_unittest.cc
@@ -13,7 +13,6 @@
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/view_targeter.h"
 #include "ui/views/view_targeter_delegate.h"
-#include "ui/views/views_switches.h"
 #include "ui/views/widget/root_view.h"
 
 namespace views {
@@ -399,13 +398,7 @@
   details.set_bounding_box(bounding_box);
   tap = GestureEventForTest(details);
 
-  // This only applies if rect-based targeting is enabled.
-  if (views::switches::IsRectBasedTargetingEnabled()) {
-    EXPECT_EQ(content, targeter->FindTargetForEvent(root_view, &tap));
-  } else {
-    EXPECT_EQ(widget.GetRootView(),
-              targeter->FindTargetForEvent(root_view, &tap));
-  }
+  EXPECT_EQ(content, targeter->FindTargetForEvent(root_view, &tap));
 
   // A gesture event not overlapping the contents view by at least
   // 60% and not having its center within the contents view should
diff --git a/ui/views/views_switches.cc b/ui/views/views_switches.cc
index 79fe257..cdf8e39 100644
--- a/ui/views/views_switches.cc
+++ b/ui/views/views_switches.cc
@@ -4,7 +4,6 @@
 
 #include "ui/views/views_switches.h"
 
-#include "base/command_line.h"
 #include "build/build_config.h"
 
 namespace views {
@@ -12,22 +11,8 @@
 
 // Please keep alphabetized.
 
-// Specifies if a heuristic should be used to determine the most probable
-// target of a gesture, where the touch region is represented by a rectangle.
-const char kDisableViewsRectBasedTargeting[] =
-    "disable-views-rect-based-targeting";
-
 // Draws a semitransparent rect to indicate the bounds of each view.
 const char kDrawViewBoundsRects[] = "draw-view-bounds-rects";
 
-bool IsRectBasedTargetingEnabled() {
-#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_LINUX)
-  return !base::CommandLine::ForCurrentProcess()->HasSwitch(
-      kDisableViewsRectBasedTargeting);
-#else
-  return false;
-#endif
-}
-
 }  // namespace switches
 }  // namespace views
diff --git a/ui/views/views_switches.h b/ui/views/views_switches.h
index bb506539..817bf138 100644
--- a/ui/views/views_switches.h
+++ b/ui/views/views_switches.h
@@ -13,12 +13,8 @@
 namespace switches {
 
 // Please keep alphabetized.
-VIEWS_EXPORT extern const char kDisableViewsRectBasedTargeting[];
 VIEWS_EXPORT extern const char kDrawViewBoundsRects[];
 
-// Returns true if rect-based targeting in views should be used.
-VIEWS_EXPORT bool IsRectBasedTargetingEnabled();
-
 }  // namespace switches
 }  // namespace views
 
diff --git a/ui/views/widget/root_view_targeter.cc b/ui/views/widget/root_view_targeter.cc
index 6cc41f274..4f11b53 100644
--- a/ui/views/widget/root_view_targeter.cc
+++ b/ui/views/widget/root_view_targeter.cc
@@ -31,12 +31,10 @@
     return root_view_->gesture_handler_;
   }
 
-  // If rect-based targeting is enabled, use the gesture's bounding box to
-  // determine the target. Otherwise use the center point of the gesture's
-  // bounding box to determine the target.
+  // If non-empty, use the gesture's bounding box to determine the target.
+  // Otherwise use the center point of the gesture's bounding box.
   gfx::Rect rect(gesture.location(), gfx::Size(1, 1));
-  if (views::switches::IsRectBasedTargetingEnabled() &&
-      !gesture.details().bounding_box().IsEmpty()) {
+  if (!gesture.details().bounding_box().IsEmpty()) {
     // TODO(tdanderson): Pass in the bounding box to GetEventHandlerForRect()
     // once crbug.com/313392 is resolved.
     rect.set_size(gesture.details().bounding_box().size());
diff --git a/ui/webui/resources/js/i18n_behavior.js b/ui/webui/resources/js/i18n_behavior.js
index 89e1d8a..931f8c8 100644
--- a/ui/webui/resources/js/i18n_behavior.js
+++ b/ui/webui/resources/js/i18n_behavior.js
@@ -49,7 +49,7 @@
     var htmlStr =
         parseHtmlSubset('<b>' + rawString + '</b>').firstChild.innerHTML;
     // TODO(dschuyler): use textContent rather than innerHTML; remove replace().
-    return htmlStr.replace('&nbsp;', '\u00a0');
+    return htmlStr.replace(/&nbsp;/g, '\u00a0');
   },
 
   /**