Merge from Chromium at DEPS revision 38.0.2125.57

This commit was generated by merge_to_master.py.

Change-Id: Ie1b6887c9fab8b861e837a7c2b4805b7d8b5109a
diff --git a/NOTICE b/NOTICE
index 82d98d9..d49a5cc 100644
--- a/NOTICE
+++ b/NOTICE
@@ -9482,134 +9482,6 @@
 
 Khronos and OpenMAX are trademarks of the Khronos Group Inc. 
 
-
-  LICENSE ISSUES
-  ==============
-
-  The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
-  the OpenSSL License and the original SSLeay license apply to the toolkit.
-  See below for the actual license texts. Actually both licenses are BSD-style
-  Open Source licenses. In case of any license issues related to OpenSSL
-  please contact openssl-core@openssl.org.
-
-  OpenSSL License
-  ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2011 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-
 Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
                     Jean-Marc Valin, Timothy B. Terriberry,
                     CSIRO, Gregory Maxwell, Mark Borgerding,
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
index ea98629..60896e8 100644
--- a/android_webview/android_webview.gyp
+++ b/android_webview/android_webview.gyp
@@ -118,7 +118,6 @@
         '../printing/printing.gyp:printing',
         '../skia/skia.gyp:skia',
         '../third_party/WebKit/public/blink.gyp:blink',
-        '../v8/tools/gyp/v8.gyp:v8',
         '../ui/gl/gl.gyp:gl',
         '../ui/shell_dialogs/shell_dialogs.gyp:shell_dialogs',
         '../webkit/common/gpu/webkit_gpu.gyp:webkit_gpu',
@@ -240,8 +239,6 @@
         'public/browser/draw_gl.h',
         'renderer/aw_content_renderer_client.cc',
         'renderer/aw_content_renderer_client.h',
-        'renderer/aw_execution_termination_filter.cc',
-        'renderer/aw_execution_termination_filter.h',
         'renderer/aw_key_systems.cc',
         'renderer/aw_key_systems.h',
         'renderer/aw_permission_client.cc',
diff --git a/android_webview/android_webview_common.target.darwin-arm.mk b/android_webview/android_webview_common.target.darwin-arm.mk
index daa14c1..5a80631 100644
--- a/android_webview/android_webview_common.target.darwin-arm.mk
+++ b/android_webview/android_webview_common.target.darwin-arm.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -223,6 +221,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -230,7 +229,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -385,6 +383,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -392,7 +391,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.darwin-arm64.mk b/android_webview/android_webview_common.target.darwin-arm64.mk
index 55add5d..1d8382f 100644
--- a/android_webview/android_webview_common.target.darwin-arm64.mk
+++ b/android_webview/android_webview_common.target.darwin-arm64.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -212,6 +210,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -219,7 +218,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -362,6 +360,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -369,7 +368,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.darwin-mips.mk b/android_webview/android_webview_common.target.darwin-mips.mk
index 44cfa0b..f6d7e6f 100644
--- a/android_webview/android_webview_common.target.darwin-mips.mk
+++ b/android_webview/android_webview_common.target.darwin-mips.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -217,6 +215,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -224,7 +223,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -373,6 +371,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -380,7 +379,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.darwin-x86.mk b/android_webview/android_webview_common.target.darwin-x86.mk
index 51c88f5..cbb4298 100644
--- a/android_webview/android_webview_common.target.darwin-x86.mk
+++ b/android_webview/android_webview_common.target.darwin-x86.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -218,6 +216,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -225,7 +224,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -374,6 +372,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -381,7 +380,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.darwin-x86_64.mk b/android_webview/android_webview_common.target.darwin-x86_64.mk
index 170a736..a3dd6d9 100644
--- a/android_webview/android_webview_common.target.darwin-x86_64.mk
+++ b/android_webview/android_webview_common.target.darwin-x86_64.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -217,6 +215,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -224,7 +223,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -372,6 +370,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -379,7 +378,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.linux-arm.mk b/android_webview/android_webview_common.target.linux-arm.mk
index daa14c1..5a80631 100644
--- a/android_webview/android_webview_common.target.linux-arm.mk
+++ b/android_webview/android_webview_common.target.linux-arm.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -223,6 +221,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -230,7 +229,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -385,6 +383,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -392,7 +391,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.linux-arm64.mk b/android_webview/android_webview_common.target.linux-arm64.mk
index 55add5d..1d8382f 100644
--- a/android_webview/android_webview_common.target.linux-arm64.mk
+++ b/android_webview/android_webview_common.target.linux-arm64.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -212,6 +210,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -219,7 +218,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -362,6 +360,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -369,7 +368,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.linux-mips.mk b/android_webview/android_webview_common.target.linux-mips.mk
index 44cfa0b..f6d7e6f 100644
--- a/android_webview/android_webview_common.target.linux-mips.mk
+++ b/android_webview/android_webview_common.target.linux-mips.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -217,6 +215,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -224,7 +223,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -373,6 +371,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -380,7 +379,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.linux-x86.mk b/android_webview/android_webview_common.target.linux-x86.mk
index 51c88f5..cbb4298 100644
--- a/android_webview/android_webview_common.target.linux-x86.mk
+++ b/android_webview/android_webview_common.target.linux-x86.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -218,6 +216,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -225,7 +224,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -374,6 +372,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -381,7 +380,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/android_webview_common.target.linux-x86_64.mk b/android_webview/android_webview_common.target.linux-x86_64.mk
index 170a736..a3dd6d9 100644
--- a/android_webview/android_webview_common.target.linux-x86_64.mk
+++ b/android_webview/android_webview_common.target.linux-x86_64.mk
@@ -16,7 +16,6 @@
 	$(call intermediates-dir-for,GYP,skia_skia_gyp,,,$(GYP_VAR_PREFIX))/skia.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,skia_skia_library_gyp,,,$(GYP_VAR_PREFIX))/skia_skia_library_gyp.a \
 	$(call intermediates-dir-for,GYP,third_party_WebKit_public_blink_gyp,,,$(GYP_VAR_PREFIX))/blink.stamp \
-	$(call intermediates-dir-for,GYP,v8_tools_gyp_v8_gyp,,,$(GYP_VAR_PREFIX))/v8.stamp \
 	$(call intermediates-dir-for,STATIC_LIBRARIES,ui_gl_gl_gyp,,,$(GYP_VAR_PREFIX))/ui_gl_gl_gyp.a \
 	$(call intermediates-dir-for,GYP,android_webview_android_webview_pak_gyp,,,$(GYP_VAR_PREFIX))/android_webview_pak.stamp
 
@@ -80,7 +79,6 @@
 	android_webview/lib/aw_browser_dependency_factory_impl.cc \
 	android_webview/lib/main/aw_main_delegate.cc \
 	android_webview/renderer/aw_content_renderer_client.cc \
-	android_webview/renderer/aw_execution_termination_filter.cc \
 	android_webview/renderer/aw_key_systems.cc \
 	android_webview/renderer/aw_permission_client.cc \
 	android_webview/renderer/aw_render_process_observer.cc \
@@ -217,6 +215,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -224,7 +223,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
@@ -372,6 +370,7 @@
 	$(PWD)/external/icu/icu4c/source/i18n \
 	$(LOCAL_PATH)/third_party/npapi \
 	$(LOCAL_PATH)/third_party/npapi/bindings \
+	$(LOCAL_PATH)/v8/include \
 	$(LOCAL_PATH)/third_party/libpng \
 	$(LOCAL_PATH)/third_party/zlib \
 	$(LOCAL_PATH)/third_party/libwebp \
@@ -379,7 +378,6 @@
 	$(LOCAL_PATH)/third_party/qcms/src \
 	$(LOCAL_PATH)/third_party/iccjpeg \
 	$(PWD)/external/jpeg \
-	$(LOCAL_PATH)/v8/include \
 	$(gyp_shared_intermediate_dir)/ui/gl \
 	$(LOCAL_PATH)/third_party/mesa/src/include \
 	$(PWD)/frameworks/wilhelm/include \
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc
index 93ab0a8..7a3c703 100644
--- a/android_webview/browser/browser_view_renderer.cc
+++ b/android_webview/browser/browser_view_renderer.cc
@@ -717,6 +717,9 @@
         FROM_HERE,
         fallback_tick_fired_.callback(),
         base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds));
+  } else {
+    // Pretend we just composited to unblock further invalidates.
+    DidComposite();
   }
 }
 
@@ -729,8 +732,12 @@
   // This should only be called if OnDraw or DrawGL did not come in time, which
   // means block_invalidates_ must still be true.
   DCHECK(block_invalidates_);
-  if (compositor_needs_continuous_invalidate_ && compositor_)
+  if (compositor_needs_continuous_invalidate_ && compositor_) {
     ForceFakeCompositeSW();
+  } else {
+    // Pretend we just composited to unblock further invalidates.
+    DidComposite();
+  }
 }
 
 void BrowserViewRenderer::ForceFakeCompositeSW() {
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index 6a3d54b..c2d1a6d 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -53,16 +53,17 @@
       attributes, &attribs_for_gles2);
   attribs_for_gles2.lose_context_when_out_of_memory = true;
 
-  scoped_ptr<gpu::GLInProcessContext> context(
-      gpu::GLInProcessContext::Create(service,
-                                      surface,
-                                      surface->IsOffscreen(),
-                                      gfx::kNullAcceleratedWidget,
-                                      surface->GetSize(),
-                                      share_context,
-                                      false /* share_resources */,
-                                      attribs_for_gles2,
-                                      gpu_preference));
+  scoped_ptr<gpu::GLInProcessContext> context(gpu::GLInProcessContext::Create(
+      service,
+      surface,
+      surface->IsOffscreen(),
+      gfx::kNullAcceleratedWidget,
+      surface->GetSize(),
+      share_context,
+      false /* share_resources */,
+      attribs_for_gles2,
+      gpu_preference,
+      gpu::GLInProcessContextSharedMemoryLimits()));
   DCHECK(context.get());
 
   return webkit::gpu::ContextProviderInProcess::Create(
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc
index 22666fb..6e39cd7 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.cc
+++ b/android_webview/browser/net/aw_url_request_context_getter.cc
@@ -208,11 +208,6 @@
   ApplyCmdlineOverridesToURLRequestContextBuilder(&builder);
 
   url_request_context_.reset(builder.Build());
-  channel_id_service_.reset(
-      new net::ChannelIDService(
-          new net::DefaultChannelIDStore(NULL),
-          base::WorkerPool::GetTaskRunner(true)));
-  url_request_context_->set_channel_id_service(channel_id_service_.get());
   // TODO(mnaganov): Fix URLRequestContextBuilder to use proper threads.
   net::HttpNetworkSession::Params network_session_params;
 
diff --git a/android_webview/browser/net/aw_url_request_context_getter.h b/android_webview/browser/net/aw_url_request_context_getter.h
index 712893a..1ec4123 100644
--- a/android_webview/browser/net/aw_url_request_context_getter.h
+++ b/android_webview/browser/net/aw_url_request_context_getter.h
@@ -11,7 +11,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "content/public/browser/content_browser_client.h"
 #include "net/http/http_network_session.h"
-#include "net/ssl/channel_id_service.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_job_factory.h"
 
@@ -75,7 +74,6 @@
       data_reduction_proxy_auth_request_handler_;
   scoped_ptr<net::URLRequestJobFactory> job_factory_;
   scoped_ptr<net::HttpTransactionFactory> main_http_factory_;
-  scoped_ptr<net::ChannelIDService> channel_id_service_;
 
   // ProtocolHandlers and interceptors are stored here between
   // SetHandlersAndInterceptors() and the first GetURLRequestContext() call.
diff --git a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
index 676616a..0428baa 100644
--- a/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
+++ b/android_webview/browser/renderer_host/aw_render_view_host_ext.cc
@@ -99,10 +99,6 @@
   Send(new AwViewMsg_SetJsOnlineProperty(network_up));
 }
 
-void AwRenderViewHostExt::SendCheckRenderThreadResponsiveness() {
-  Send(new AwViewMsg_CheckRenderThreadResponsiveness());
-}
-
 void AwRenderViewHostExt::RenderViewCreated(
     content::RenderViewHost* render_view_host) {
   Send(new AwViewMsg_SetBackgroundColor(web_contents()->GetRoutingID(),
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 773e504..635c7fc 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
@@ -77,8 +77,6 @@
   void SetBackgroundColor(SkColor c);
   void SetJsOnlineProperty(bool network_up);
 
-  void SendCheckRenderThreadResponsiveness();
-
  private:
   // content::WebContentsObserver implementation.
   virtual void RenderViewCreated(content::RenderViewHost* view_host) OVERRIDE;
diff --git a/android_webview/common/render_view_messages.h b/android_webview/common/render_view_messages.h
index 7592fb7..9354db5 100644
--- a/android_webview/common/render_view_messages.h
+++ b/android_webview/common/render_view_messages.h
@@ -74,10 +74,6 @@
 IPC_MESSAGE_CONTROL1(AwViewMsg_SetJsOnlineProperty,
                      bool /* network_up */)
 
-// Sent prior to making a navigation via loadUrl to make sure that
-// render thread isn't stuck in a loop induced by JavaScript code.
-IPC_MESSAGE_CONTROL0(AwViewMsg_CheckRenderThreadResponsiveness)
-
 //-----------------------------------------------------------------------------
 // RenderView messages
 // These are messages sent from the renderer to the browser process.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index 436e65c..e5609f0 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -182,6 +182,7 @@
     private final AwLayoutChangeListener mLayoutChangeListener;
     private final Context mContext;
     private ContentViewCore mContentViewCore;
+    private WindowAndroid mWindowAndroid;
     private final AwContentsClient mContentsClient;
     private final AwContentViewClient mContentViewClient;
     private WebContentsObserverAndroid mWebContentsObserver;
@@ -615,12 +616,11 @@
             Context context, InternalAccessDelegate internalDispatcher, long nativeWebContents,
             GestureStateListener gestureStateListener,
             ContentViewClient contentViewClient,
-            ContentViewCore.ZoomControlsDelegate zoomControlsDelegate) {
+            ContentViewCore.ZoomControlsDelegate zoomControlsDelegate,
+            WindowAndroid windowAndroid) {
         ContentViewCore contentViewCore = new ContentViewCore(context);
         contentViewCore.initialize(containerView, internalDispatcher, nativeWebContents,
-                context instanceof Activity ?
-                        new ActivityWindowAndroid((Activity) context) :
-                        new WindowAndroid(context.getApplicationContext()));
+                windowAndroid);
         contentViewCore.addGestureStateListener(gestureStateListener);
         contentViewCore.setContentViewClient(contentViewClient);
         contentViewCore.setZoomControlsDelegate(zoomControlsDelegate);
@@ -756,9 +756,13 @@
         mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents));
 
         long nativeWebContents = nativeGetWebContents(mNativeAwContents);
+
+        mWindowAndroid = mContext instanceof Activity ?
+                new ActivityWindowAndroid((Activity) mContext) :
+                new WindowAndroid(mContext.getApplicationContext());
         mContentViewCore = createAndInitializeContentViewCore(
                 mContainerView, mContext, mInternalAccessAdapter, nativeWebContents,
-                new AwGestureStateListener(), mContentViewClient, mZoomControls);
+                new AwGestureStateListener(), mContentViewClient, mZoomControls, mWindowAndroid);
         nativeSetJavaPeers(mNativeAwContents, this, mWebContentsDelegate, mContentsClientBridge,
                 mIoThreadClient, mInterceptNavigationDelegate);
         installWebContentsObserver();
@@ -1057,8 +1061,6 @@
      * @param params Parameters for this load.
      */
     public void loadUrl(LoadUrlParams params) {
-        if (mNativeAwContents == 0) return;
-
         if (params.getLoadUrlType() == LoadUrlParams.LOAD_TYPE_DATA &&
                 !params.isBaseUrlDataScheme()) {
             // This allows data URLs with a non-data base URL access to file:///android_asset/ and
@@ -1097,11 +1099,12 @@
             }
         }
 
-        nativeSetExtraHeadersForUrl(
-                mNativeAwContents, params.getUrl(), params.getExtraHttpRequestHeadersString());
+        if (mNativeAwContents != 0) {
+            nativeSetExtraHeadersForUrl(
+                    mNativeAwContents, params.getUrl(), params.getExtraHttpRequestHeadersString());
+        }
         params.setExtraHeaders(new HashMap<String, String>());
 
-        nativeSendCheckRenderThreadResponsiveness(mNativeAwContents);
         mContentViewCore.loadUrl(params);
 
         // The behavior of WebViewClassic uses the populateVisitedLinks callback in WebKit.
@@ -2040,10 +2043,10 @@
 
     @CalledByNative
     private void postInvalidateOnAnimation() {
-        if (SUPPORTS_ON_ANIMATION) {
+        if (SUPPORTS_ON_ANIMATION && !mWindowAndroid.isInsideVSync()) {
             mContainerView.postInvalidateOnAnimation();
         } else {
-            mContainerView.postInvalidate();
+            mContainerView.invalidate();
         }
     }
 
@@ -2489,7 +2492,6 @@
     private native void nativeClearView(long nativeAwContents);
     private native void nativeSetExtraHeadersForUrl(long nativeAwContents,
             String url, String extraHeaders);
-    private native void nativeSendCheckRenderThreadResponsiveness(long nativeAwContents);
 
     private native void nativeInvokeGeolocationCallback(
             long nativeAwContents, boolean value, String requestingFrame);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwJavaBridgeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwJavaBridgeTest.java
new file mode 100644
index 0000000..6a15244
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwJavaBridgeTest.java
@@ -0,0 +1,74 @@
+// 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.
+
+package org.chromium.android_webview.test;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.android_webview.AwContents;
+import org.chromium.base.test.util.Feature;
+import org.chromium.content.browser.JavascriptInterface;
+
+/**
+ * Test suite for the WebView specific JavaBridge features.
+ */
+public class AwJavaBridgeTest extends AwTestBase {
+
+    private TestAwContentsClient mContentsClient = new TestAwContentsClient();
+    private AwTestContainerView mTestContainerView;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestContainerView = createAwTestContainerViewOnMainSync(mContentsClient);
+    }
+
+    @SmallTest
+    @Feature({"AndroidWebView", "Android-JavaBridge"})
+    public void testDestroyFromJavaObject() throws Throwable {
+        final String HTML = "<html>Hello World</html>";
+        final TestAwContentsClient client2 = new TestAwContentsClient();
+        final AwTestContainerView view2 = createAwTestContainerViewOnMainSync(client2);
+        final AwContents awContents = mTestContainerView.getAwContents();
+
+        class Test {
+            @JavascriptInterface
+            public void destroy() {
+                try {
+                    runTestOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                awContents.destroy();
+                            }
+                    });
+                    // Destroying one AwContents from within the JS callback should still
+                    // leave others functioning.
+                    loadDataSync(view2.getAwContents(), client2.getOnPageFinishedHelper(),
+                            HTML, "text/html", false);
+                } catch (Throwable t) {
+                    throw new RuntimeException(t);
+                }
+            }
+        }
+
+        enableJavaScriptOnUiThread(awContents);
+        runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    awContents.addPossiblyUnsafeJavascriptInterface(new Test(), "test", null);
+            }
+        });
+
+        loadDataSync(awContents, mContentsClient.getOnPageFinishedHelper(), HTML,
+                "text/html", false);
+
+        // Ensure the JS interface object is there, and invoke the test method.
+        assertEquals("\"function\"", executeJavaScriptAndWaitForResult(
+                awContents, mContentsClient, "typeof test.destroy"));
+        awContents.evaluateJavaScript("test.destroy()", null);
+
+        client2.getOnPageFinishedHelper().waitForCallback(
+                client2.getOnPageFinishedHelper().getCallCount());
+    }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/LoadUrlTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/LoadUrlTest.java
index 77fb370..4a6bab5 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/LoadUrlTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/LoadUrlTest.java
@@ -4,12 +4,9 @@
 
 package org.chromium.android_webview.test;
 
-import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Pair;
 
-import junit.framework.Assert;
-
 import org.apache.http.Header;
 import org.apache.http.HttpRequest;
 import org.chromium.android_webview.AwContents;
@@ -334,71 +331,4 @@
             if (webServer != null) webServer.shutdown();
         }
     }
-
-    private static class TestController {
-        private final Object mLock = new Object();
-        private boolean mIsReady = false;
-        public void notifyPageIsReady() {
-            synchronized (mLock) {
-                mIsReady = true;
-                mLock.notify();
-            }
-        }
-        public void waitUntilIsReady() {
-            synchronized (mLock) {
-                while (!mIsReady) {
-                    try {
-                        mLock.wait(WAIT_TIMEOUT_MS);
-                    } catch (Exception e) {
-                        continue;
-                    }
-                    if (!mIsReady) {
-                        Assert.fail("Wait timed out");
-                    }
-                }
-                mIsReady = false;
-            }
-        }
-    }
-
-    // Verify that it is possible to interrupt JS scripts stuck in an infinite loop
-    // by calling loadUrl on a WebView.
-    @LargeTest
-    @Feature({"AndroidWebView"})
-    public void testLoadUrlInterruptsLoopedScripts() throws Throwable {
-        final String infiniteLoopPage =
-            "<html><head>" +
-            "  <script>" +
-            "    function infiniteLoop() {" +
-            "      test.notifyPageIsReady();" +
-            "      while(1);" +
-            "    }" +
-            "  </script>" +
-            "</head><body onload='setTimeout(infiniteLoop, 0)'>" +
-            "</body></html>";
-        final String simplePage = "<html><body onload='test.notifyPageIsReady()'></body></html>";
-        final String expectedTitle = "PASS";
-        final String pageWithTitle = "<html><body onload='document.title=\"" + expectedTitle +
-                "\"; test.notifyPageIsReady()'></body></html>";
-
-        final AwTestContainerView testContainerView =
-                createAwTestContainerViewOnMainSync(new TestAwContentsClient());
-        final AwContents awContents = testContainerView.getAwContents();
-        getAwSettingsOnUiThread(awContents).setJavaScriptEnabled(true);
-        final TestController testController = new TestController();
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                awContents.addPossiblyUnsafeJavascriptInterface(testController, "test", null);
-            }
-        });
-        loadDataAsync(awContents, infiniteLoopPage, "text/html", false);
-        testController.waitUntilIsReady();
-        loadDataAsync(awContents, simplePage, "text/html", false);
-        testController.waitUntilIsReady();
-        // Load another page that runs JS to make sure that the WebView is still functional.
-        loadDataAsync(awContents, pageWithTitle, "text/html", false);
-        testController.waitUntilIsReady();
-        assertEquals(expectedTitle, getTitleOnUiThread(awContents));
-    }
 }
diff --git a/android_webview/lib/main/webview_entry_point.cc b/android_webview/lib/main/webview_entry_point.cc
index 1aa1d27..73bf8f7 100644
--- a/android_webview/lib/main/webview_entry_point.cc
+++ b/android_webview/lib/main/webview_entry_point.cc
@@ -6,6 +6,7 @@
 #include "android_webview/native/android_webview_jni_registrar.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_registrar.h"
+#include "base/android/jni_utils.h"
 #include "base/android/library_loader/library_loader_hooks.h"
 #include "components/navigation_interception/component_jni_registrar.h"
 #include "components/web_contents_delegate_android/component_jni_registrar.h"
@@ -47,6 +48,9 @@
   if (!android_webview::RegisterJni(env))
     return -1;
 
+  base::android::InitReplacementClassLoader(env,
+                                            base::android::GetClassLoader(env));
+
   content::SetContentMainDelegate(new android_webview::AwMainDelegate());
 
   // Initialize url lib here while we are still single-threaded, in case we use
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 4c8a4f2..ed44b77 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -1143,11 +1143,6 @@
                                     extra_headers);
 }
 
-void AwContents::SendCheckRenderThreadResponsiveness(JNIEnv* env, jobject obj) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  render_view_host_ext_->SendCheckRenderThreadResponsiveness();
-}
-
 void AwContents::SetJsOnlineProperty(JNIEnv* env,
                                      jobject obj,
                                      jboolean network_up) {
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index da13d6f..a390375 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -127,7 +127,6 @@
   void ClearView(JNIEnv* env, jobject obj);
   void SetExtraHeadersForUrl(JNIEnv* env, jobject obj,
                              jstring url, jstring extra_headers);
-  void SendCheckRenderThreadResponsiveness(JNIEnv* env, jobject obj);
 
   void DrawGL(AwDrawGLInfo* draw_info);
 
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc
index f4f0b1e..9ae387b 100644
--- a/android_webview/renderer/aw_content_renderer_client.cc
+++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -7,7 +7,6 @@
 #include "android_webview/common/aw_resource.h"
 #include "android_webview/common/render_view_messages.h"
 #include "android_webview/common/url_constants.h"
-#include "android_webview/renderer/aw_execution_termination_filter.h"
 #include "android_webview/renderer/aw_key_systems.h"
 #include "android_webview/renderer/aw_permission_client.h"
 #include "android_webview/renderer/aw_render_frame_ext.h"
@@ -32,7 +31,6 @@
 #include "third_party/WebKit/public/platform/WebURLError.h"
 #include "third_party/WebKit/public/platform/WebURLRequest.h"
 #include "third_party/WebKit/public/web/WebFrame.h"
-#include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebNavigationType.h"
 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
 #include "url/gurl.h"
@@ -63,17 +61,6 @@
 
   visited_link_slave_.reset(new visitedlink::VisitedLinkSlave);
   thread->AddObserver(visited_link_slave_.get());
-
-  execution_termination_filter_ = new AwExecutionTerminationFilter(
-      thread->GetIOMessageLoopProxy(),
-      thread->GetMessageLoop()->message_loop_proxy());
-  thread->AddFilter(execution_termination_filter_.get());
-  thread->AddObserver(this);
-}
-
-void AwContentRendererClient::WebKitInitialized() {
-  execution_termination_filter_->SetRenderThreadIsolate(
-      blink::mainThreadIsolate());
 }
 
 bool AwContentRendererClient::HandleNavigation(
diff --git a/android_webview/renderer/aw_content_renderer_client.h b/android_webview/renderer/aw_content_renderer_client.h
index dc02cce..30f44b4 100644
--- a/android_webview/renderer/aw_content_renderer_client.h
+++ b/android_webview/renderer/aw_content_renderer_client.h
@@ -16,10 +16,7 @@
 
 namespace android_webview {
 
-class AwExecutionTerminationFilter;
-
-class AwContentRendererClient : public content::ContentRendererClient,
-                                public content::RenderProcessObserver {
+class AwContentRendererClient : public content::ContentRendererClient {
  public:
   AwContentRendererClient();
   virtual ~AwContentRendererClient();
@@ -53,13 +50,9 @@
                                 blink::WebNavigationPolicy default_policy,
                                 bool is_redirect) OVERRIDE;
 
-  // content::RenderProcessObserver implementation.
-  virtual void WebKitInitialized() OVERRIDE;
-
  private:
   scoped_ptr<AwRenderProcessObserver> aw_render_process_observer_;
   scoped_ptr<visitedlink::VisitedLinkSlave> visited_link_slave_;
-  scoped_refptr<AwExecutionTerminationFilter> execution_termination_filter_;
 };
 
 }  // namespace android_webview
diff --git a/android_webview/renderer/aw_execution_termination_filter.cc b/android_webview/renderer/aw_execution_termination_filter.cc
deleted file mode 100644
index 75f130d..0000000
--- a/android_webview/renderer/aw_execution_termination_filter.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "android_webview/renderer/aw_execution_termination_filter.h"
-
-#include <v8.h>
-
-#include "android_webview/common/render_view_messages.h"
-#include "base/message_loop/message_loop_proxy.h"
-
-namespace {
-const int kTerminationTimeoutInSeconds = 3;
-}  // namespace
-
-namespace android_webview {
-
-AwExecutionTerminationFilter::AwExecutionTerminationFilter(
-    const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
-    const scoped_refptr<base::MessageLoopProxy>& main_message_loop)
-    : io_message_loop_(io_message_loop),
-      main_message_loop_(main_message_loop),
-      render_thread_isolate_(NULL) {
-}
-
-AwExecutionTerminationFilter::~AwExecutionTerminationFilter() {
-}
-
-void AwExecutionTerminationFilter::SetRenderThreadIsolate(
-    v8::Isolate* isolate) {
-  render_thread_isolate_ = isolate;
-}
-
-bool AwExecutionTerminationFilter::OnMessageReceived(
-    const IPC::Message& message) {
-  bool handled = true;
-  IPC_BEGIN_MESSAGE_MAP(AwExecutionTerminationFilter, message)
-    IPC_MESSAGE_HANDLER(AwViewMsg_CheckRenderThreadResponsiveness,
-                        OnCheckRenderThreadResponsiveness)
-    IPC_MESSAGE_UNHANDLED(handled = false)
-  IPC_END_MESSAGE_MAP()
-  return handled;
-}
-
-void AwExecutionTerminationFilter::OnCheckRenderThreadResponsiveness() {
-  termination_timer_.Start(
-      FROM_HERE,
-      base::TimeDelta::FromSeconds(kTerminationTimeoutInSeconds),
-      base::Bind(&AwExecutionTerminationFilter::TerminateExecution, this));
-  // Post a request to stop the timer via render thread's message loop
-  // to ensure that render thread is responsive.
-  main_message_loop_->PostTask(
-      FROM_HERE,
-      base::Bind(&AwExecutionTerminationFilter::StopTimerOnMainThread,
-                 this));
-}
-
-void AwExecutionTerminationFilter::StopTimerOnMainThread() {
-  io_message_loop_->PostTask(
-      FROM_HERE,
-      base::Bind(&AwExecutionTerminationFilter::StopTimer, this));
-}
-
-void AwExecutionTerminationFilter::StopTimer() {
-  termination_timer_.Stop();
-}
-
-void AwExecutionTerminationFilter::TerminateExecution() {
-  if (render_thread_isolate_) {
-    LOG(WARNING) << "Trying to terminate JavaScript execution because "
-        "renderer is unresponsive";
-    v8::V8::TerminateExecution(render_thread_isolate_);
-  }
-}
-
-}  // namespace android_webview
diff --git a/android_webview/renderer/aw_execution_termination_filter.h b/android_webview/renderer/aw_execution_termination_filter.h
deleted file mode 100644
index 14b88b1..0000000
--- a/android_webview/renderer/aw_execution_termination_filter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ANDROID_WEBVIEW_RENDERER_AW_EXECUTION_TERMINATION_FILTER_H_
-#define ANDROID_WEBVIEW_RENDERER_AW_EXECUTION_TERMINATION_FILTER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/timer/timer.h"
-#include "ipc/message_filter.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-namespace v8 {
-class Isolate;
-}
-
-namespace android_webview {
-
-// The purpose of AwExecutionTerminationFilter is to attempt to terminate
-// any JavaScript code that is stuck in a loop before doing a navigation
-// originating from a Andoird WebView URL loading functions.
-//
-// This is how it works. AwExecutionTerminationFilter is created on render
-// thread. It listens on IO thread for navigation requests coming from
-// AwContents.loadUrl calls. On each such a request, it posts a delayed
-// cancellable task on the IO thread's message loop and, at the same time, posts
-// a cancellation task on the render thread's message loop. If render thread
-// is not stuck, the cancellation task runs and cancels the delayed task.
-// Otherwise, the delayed task runs and terminates execution of JS code
-// from the IO thread.
-class AwExecutionTerminationFilter : public IPC::MessageFilter {
- public:
-  AwExecutionTerminationFilter(
-      const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
-      const scoped_refptr<base::MessageLoopProxy>& main_message_loop);
-
-  void SetRenderThreadIsolate(v8::Isolate* isolate);
-
- private:
-  virtual ~AwExecutionTerminationFilter();
-
-  // IPC::MessageFilter methods.
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
-  void OnCheckRenderThreadResponsiveness();
-  void StopTimerOnMainThread();
-  void StopTimer();
-  void TerminateExecution();
-
-  const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
-  const scoped_refptr<base::MessageLoopProxy> main_message_loop_;
-
-  v8::Isolate* render_thread_isolate_;
-  base::OneShotTimer<AwExecutionTerminationFilter> termination_timer_;
-
-  DISALLOW_COPY_AND_ASSIGN(AwExecutionTerminationFilter);
-};
-
-}  // namespace android_webview
-
-#endif  // ANDROID_WEBVIEW_RENDERER_AW_EXECUTION_TERMINATION_FILTER_H_
diff --git a/ash/shell.cc b/ash/shell.cc
index 8254610..fd06ea8 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -308,7 +308,7 @@
 }
 
 void Shell::ToggleAppList(aura::Window* window) {
-  if (GetAppListTargetVisibility()) {
+  if (app_list_controller_ && app_list_controller_->IsVisible()) {
     DismissAppList();
     return;
   }
diff --git a/ash/system/web_notification/web_notification_tray.cc b/ash/system/web_notification/web_notification_tray.cc
index e42c0f9..900dd93 100644
--- a/ash/system/web_notification/web_notification_tray.cc
+++ b/ash/system/web_notification/web_notification_tray.cc
@@ -91,8 +91,8 @@
     }
     views::TrayBubbleView* bubble_view = views::TrayBubbleView::Create(
         tray->GetBubbleWindowContainer(), anchor, tray, &init_params);
-    bubble_view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE);
     bubble_wrapper_.reset(new TrayBubbleWrapper(tray, bubble_view));
+    bubble_view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE);
     bubble->InitializeContents(bubble_view);
   }
 
diff --git a/ash/wm/lock_layout_manager_unittest.cc b/ash/wm/lock_layout_manager_unittest.cc
index 70984c4..b680ba2 100644
--- a/ash/wm/lock_layout_manager_unittest.cc
+++ b/ash/wm/lock_layout_manager_unittest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "ash/display/display_manager.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_util.h"
 #include "ash/shell.h"
@@ -187,7 +188,8 @@
 }
 
 TEST_F(LockLayoutManagerTest, KeyboardBounds) {
-  gfx::Rect screen_bounds = Shell::GetScreen()->GetPrimaryDisplay().bounds();
+  gfx::Display primary_display = Shell::GetScreen()->GetPrimaryDisplay();
+  gfx::Rect screen_bounds = primary_display.bounds();
 
   views::Widget::InitParams widget_params(
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -203,8 +205,30 @@
        keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_ENABLED);
   ShowKeyboard(true);
   EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
+  gfx::Rect keyboard_bounds =
+      keyboard::KeyboardController::GetInstance()->current_keyboard_bounds();
+  EXPECT_NE(keyboard_bounds, gfx::Rect());
   ShowKeyboard(false);
 
+  // When keyboard is hidden make sure that rotating the screen gives 100% of
+  // screen size to window.
+  // Repro steps for http://crbug.com/401667:
+  // 1. Set up login screen defaults: VK override disabled
+  // 2. Show/hide keyboard, make sure that no stale keyboard bounds are cached.
+  keyboard::SetKeyboardOverscrollOverride(
+       keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_DISABLED);
+  ShowKeyboard(true);
+  ShowKeyboard(false);
+  ash::DisplayManager* display_manager =
+      Shell::GetInstance()->display_manager();
+  display_manager->SetDisplayRotation(primary_display.id(),
+                                      gfx::Display::ROTATE_90);
+  primary_display = Shell::GetScreen()->GetPrimaryDisplay();
+  screen_bounds = primary_display.bounds();
+  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
+  display_manager->SetDisplayRotation(primary_display.id(),
+                                      gfx::Display::ROTATE_0);
+
   // When virtual keyboard overscroll is disabled keyboard bounds do
   // affect window bounds.
   keyboard::SetKeyboardOverscrollOverride(
@@ -212,6 +236,8 @@
   ShowKeyboard(true);
   keyboard::KeyboardController* keyboard =
         keyboard::KeyboardController::GetInstance();
+  primary_display = Shell::GetScreen()->GetPrimaryDisplay();
+  screen_bounds = primary_display.bounds();
   gfx::Rect target_bounds(screen_bounds);
   target_bounds.set_height(target_bounds.height() -
       keyboard->proxy()->GetKeyboardWindow()->bounds().height());
diff --git a/ash/wm/lock_window_state.cc b/ash/wm/lock_window_state.cc
index 5d38b59..fa1684f 100644
--- a/ash/wm/lock_window_state.cc
+++ b/ash/wm/lock_window_state.cc
@@ -167,12 +167,17 @@
       keyboard::KeyboardController::GetInstance();
   gfx::Rect keyboard_bounds;
 
-  if (keyboard_controller && !keyboard::IsKeyboardOverscrollEnabled())
+  if (keyboard_controller &&
+      !keyboard::IsKeyboardOverscrollEnabled() &&
+      keyboard_controller->keyboard_visible()) {
     keyboard_bounds = keyboard_controller->current_keyboard_bounds();
+  }
 
   gfx::Rect bounds =
       ScreenUtil::GetDisplayBoundsInParent(window_state->window());
   bounds.set_height(bounds.height() - keyboard_bounds.height());
+
+  VLOG(1) << "Updating window bounds to: " << bounds.ToString();
   window_state->SetBoundsDirect(bounds);
 }
 
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 0f83b32..e8a27b9 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -49,6 +49,8 @@
     "android/jni_registrar.h",
     "android/jni_string.cc",
     "android/jni_string.h",
+    "android/jni_utils.cc",
+    "android/jni_utils.h",
     "android/jni_weak_ref.cc",
     "android/jni_weak_ref.h",
     "android/library_loader/library_loader_hooks.cc",
@@ -1343,6 +1345,7 @@
       "android/java/src/org/chromium/base/EventLog.java",
       "android/java/src/org/chromium/base/FieldTrialList.java",
       "android/java/src/org/chromium/base/ImportantFileWriterAndroid.java",
+      "android/java/src/org/chromium/base/JNIUtils.java",
       "android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
       "android/java/src/org/chromium/base/MemoryPressureListener.java",
       "android/java/src/org/chromium/base/JavaHandlerThread.java",
diff --git a/base/android/base_jni_registrar.cc b/base/android/base_jni_registrar.cc
index a7a5fd2..b6d8a28 100644
--- a/base/android/base_jni_registrar.cc
+++ b/base/android/base_jni_registrar.cc
@@ -15,6 +15,7 @@
 #include "base/android/java_handler_thread.h"
 #include "base/android/jni_android.h"
 #include "base/android/jni_registrar.h"
+#include "base/android/jni_utils.h"
 #include "base/android/memory_pressure_listener_android.h"
 #include "base/android/path_service_android.h"
 #include "base/android/path_utils.h"
@@ -40,6 +41,7 @@
   { "FieldTrialList", base::android::RegisterFieldTrialList },
   { "ImportantFileWriterAndroid",
     base::android::RegisterImportantFileWriterAndroid },
+  { "JNIUtils", base::android::RegisterJNIUtils },
   { "MemoryPressureListenerAndroid",
       base::android::MemoryPressureListenerAndroid::Register },
   { "JavaHandlerThread", base::android::JavaHandlerThread::RegisterBindings },
diff --git a/base/android/java/src/org/chromium/base/JNIUtils.java b/base/android/java/src/org/chromium/base/JNIUtils.java
new file mode 100644
index 0000000..6f6cd54
--- /dev/null
+++ b/base/android/java/src/org/chromium/base/JNIUtils.java
@@ -0,0 +1,20 @@
+// 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.
+
+package org.chromium.base;
+
+/**
+ * This class provides JNI-related methods to the native library.
+ */
+public class JNIUtils {
+    /**
+     * This returns a ClassLoader that is capable of loading Chromium Java code. Such a ClassLoader
+     * is needed for the few cases where the JNI mechanism is unable to automatically determine the
+     * appropriate ClassLoader instance.
+     */
+    @CalledByNative
+    public static Object getClassLoader() {
+        return JNIUtils.class.getClassLoader();
+    }
+}
diff --git a/base/android/java/src/org/chromium/base/library_loader/Linker.java b/base/android/java/src/org/chromium/base/library_loader/Linker.java
index 49a76b6..7771cbf 100644
--- a/base/android/java/src/org/chromium/base/library_loader/Linker.java
+++ b/base/android/java/src/org/chromium/base/library_loader/Linker.java
@@ -1013,7 +1013,8 @@
             mRelroStart = in.readLong();
             mRelroSize = in.readLong();
             ParcelFileDescriptor fd = in.readFileDescriptor();
-            mRelroFd = fd.detachFd();
+            // If CreateSharedRelro fails, the OS file descriptor will be -1 and |fd| will be null.
+            mRelroFd = (fd == null) ? -1 : fd.detachFd();
         }
 
         // from Parcelable
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 6f080fb..e09c2d5 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -8,6 +8,7 @@
 
 #include "base/android/build_info.h"
 #include "base/android/jni_string.h"
+#include "base/android/jni_utils.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 
@@ -21,6 +22,9 @@
 // that may still be running at shutdown. There is no harm in doing this.
 base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
     g_application_context = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
+    g_class_loader = LAZY_INSTANCE_INITIALIZER;
+jmethodID g_class_loader_load_class_method_id = 0;
 
 std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
   ScopedJavaLocalRef<jclass> throwable_clazz =
@@ -118,17 +122,68 @@
   g_application_context.Get().Reset(context);
 }
 
+void InitReplacementClassLoader(JNIEnv* env,
+                                const JavaRef<jobject>& class_loader) {
+  DCHECK(g_class_loader.Get().is_null());
+  DCHECK(!class_loader.is_null());
+
+  ScopedJavaLocalRef<jclass> class_loader_clazz =
+      GetClass(env, "java/lang/ClassLoader");
+  CHECK(!ClearException(env));
+  g_class_loader_load_class_method_id =
+      env->GetMethodID(class_loader_clazz.obj(),
+                       "loadClass",
+                       "(Ljava/lang/String;)Ljava/lang/Class;");
+  CHECK(!ClearException(env));
+
+  DCHECK(env->IsInstanceOf(class_loader.obj(), class_loader_clazz.obj()));
+  g_class_loader.Get().Reset(class_loader);
+}
+
 const jobject GetApplicationContext() {
   DCHECK(!g_application_context.Get().is_null());
   return g_application_context.Get().obj();
 }
 
 ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
-  jclass clazz = env->FindClass(class_name);
+  jclass clazz;
+  if (!g_class_loader.Get().is_null()) {
+    clazz = static_cast<jclass>(
+        env->CallObjectMethod(g_class_loader.Get().obj(),
+                              g_class_loader_load_class_method_id,
+                              ConvertUTF8ToJavaString(env, class_name).obj()));
+  } else {
+    clazz = env->FindClass(class_name);
+  }
   CHECK(!ClearException(env) && clazz) << "Failed to find class " << class_name;
   return ScopedJavaLocalRef<jclass>(env, clazz);
 }
 
+jclass LazyGetClass(
+    JNIEnv* env,
+    const char* class_name,
+    base::subtle::AtomicWord* atomic_class_id) {
+  COMPILE_ASSERT(sizeof(subtle::AtomicWord) >= sizeof(jclass),
+                 AtomicWord_SmallerThan_jMethodID);
+  subtle::AtomicWord value = base::subtle::Acquire_Load(atomic_class_id);
+  if (value)
+    return reinterpret_cast<jclass>(value);
+  ScopedJavaGlobalRef<jclass> clazz;
+  clazz.Reset(GetClass(env, class_name));
+  subtle::AtomicWord null_aw = reinterpret_cast<subtle::AtomicWord>(NULL);
+  subtle::AtomicWord cas_result = base::subtle::Release_CompareAndSwap(
+      atomic_class_id,
+      null_aw,
+      reinterpret_cast<subtle::AtomicWord>(clazz.obj()));
+  if (cas_result == null_aw) {
+    // We intentionally leak the global ref since we now storing it as a raw
+    // pointer in |atomic_class_id|.
+    return clazz.Release();
+  } else {
+    return reinterpret_cast<jclass>(cas_result);
+  }
+}
+
 template<MethodID::Type type>
 jmethodID MethodID::Get(JNIEnv* env,
                         jclass clazz,
diff --git a/base/android/jni_android.h b/base/android/jni_android.h
index faf53b7..b5e5526 100644
--- a/base/android/jni_android.h
+++ b/base/android/jni_android.h
@@ -53,6 +53,15 @@
 BASE_EXPORT void InitApplicationContext(JNIEnv* env,
                                         const JavaRef<jobject>& context);
 
+// Initializes the global ClassLoader used by the GetClass and LazyGetClass
+// methods. This is needed because JNI will use the base ClassLoader when there
+// is no Java code on the stack. The base ClassLoader doesn't know about any of
+// the application classes and will fail to lookup anything other than system
+// classes.
+BASE_EXPORT void InitReplacementClassLoader(
+    JNIEnv* env,
+    const JavaRef<jobject>& class_loader);
+
 // Gets a global ref to the application context set with
 // InitApplicationContext(). Ownership is retained by the function - the caller
 // must NOT release it.
@@ -66,6 +75,17 @@
 BASE_EXPORT ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env,
                                                 const char* class_name);
 
+// The method will initialize |atomic_class_id| to contain a global ref to the
+// class. And will return that ref on subsequent calls.  It's the caller's
+// responsibility to release the ref when it is no longer needed.
+// The caller is responsible to zero-initialize |atomic_method_id|.
+// It's fine to simultaneously call this on multiple threads referencing the
+// same |atomic_method_id|.
+BASE_EXPORT jclass LazyGetClass(
+    JNIEnv* env,
+    const char* class_name,
+    base::subtle::AtomicWord* atomic_class_id);
+
 // This class is a wrapper for JNIEnv Get(Static)MethodID.
 class BASE_EXPORT MethodID {
  public:
diff --git a/base/android/jni_generator/golden_sample_for_tests_jni.h b/base/android/jni_generator/golden_sample_for_tests_jni.h
index 7dbf71e..0fcdc69 100644
--- a/base/android/jni_generator/golden_sample_for_tests_jni.h
+++ b/base/android/jni_generator/golden_sample_for_tests_jni.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -26,10 +26,13 @@
     "org/chromium/example/jni_generator/SampleForTests$InnerStructB";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_InnerStructA_clazz = NULL;
+#define InnerStructA_clazz(env) g_InnerStructA_clazz
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_SampleForTests_clazz = NULL;
+#define SampleForTests_clazz(env) g_SampleForTests_clazz
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_InnerStructB_clazz = NULL;
+#define InnerStructB_clazz(env) g_InnerStructB_clazz
 
 }  // namespace
 
@@ -99,11 +102,11 @@
     JniIntWrapper bar) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz, 0);
+      SampleForTests_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "javaMethod",
 
 "("
@@ -123,12 +126,12 @@
 static base::subtle::AtomicWord g_SampleForTests_staticJavaMethod = 0;
 static jboolean Java_SampleForTests_staticJavaMethod(JNIEnv* env) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_SampleForTests_clazz,
-      g_SampleForTests_clazz, false);
+  CHECK_CLAZZ(env, SampleForTests_clazz(env),
+      SampleForTests_clazz(env), false);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "staticJavaMethod",
 
 "("
@@ -137,7 +140,7 @@
       &g_SampleForTests_staticJavaMethod);
 
   jboolean ret =
-      env->CallStaticBooleanMethod(g_SampleForTests_clazz,
+      env->CallStaticBooleanMethod(SampleForTests_clazz(env),
           method_id);
   jni_generator::CheckException(env);
   return ret;
@@ -148,11 +151,11 @@
     obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz);
+      SampleForTests_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "packagePrivateJavaMethod",
 
 "("
@@ -171,11 +174,11 @@
     obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz);
+      SampleForTests_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "methodThatThrowsException",
 
 "("
@@ -194,12 +197,12 @@
     JniIntWrapper i,
     jstring s) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_InnerStructA_clazz,
-      g_InnerStructA_clazz, NULL);
+  CHECK_CLAZZ(env, InnerStructA_clazz(env),
+      InnerStructA_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_InnerStructA_clazz,
+      env, InnerStructA_clazz(env),
       "create",
 
 "("
@@ -211,7 +214,7 @@
       &g_InnerStructA_create);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_InnerStructA_clazz,
+      env->CallStaticObjectMethod(InnerStructA_clazz(env),
           method_id, l, as_jint(i), s);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
@@ -222,11 +225,11 @@
     {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz);
+      SampleForTests_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "addStructA",
 
 "("
@@ -246,11 +249,11 @@
     {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz);
+      SampleForTests_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "iterateAndDoSomething",
 
 "("
@@ -268,11 +271,11 @@
 static jlong Java_InnerStructB_getKey(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InnerStructB_clazz, 0);
+      InnerStructB_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InnerStructB_clazz,
+      env, InnerStructB_clazz(env),
       "getKey",
 
 "("
@@ -292,11 +295,11 @@
     Java_InnerStructB_getValue(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InnerStructB_clazz, NULL);
+      InnerStructB_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InnerStructB_clazz,
+      env, InnerStructB_clazz(env),
       "getValue",
 
 "("
@@ -379,11 +382,11 @@
 
   const int kMethodsSampleForTestsSize = arraysize(kMethodsSampleForTests);
 
-  if (env->RegisterNatives(g_SampleForTests_clazz,
+  if (env->RegisterNatives(SampleForTests_clazz(env),
                            kMethodsSampleForTests,
                            kMethodsSampleForTestsSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_SampleForTests_clazz, __FILE__);
+        env, SampleForTests_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 88332fa..4342fed 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -731,7 +731,7 @@
   def GetContent(self):
     """Returns the content of the JNI binding file."""
     template = Template("""\
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -947,11 +947,11 @@
     template = Template("""\
   const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
 
-  if (env->RegisterNatives(g_${JAVA_CLASS}_clazz,
+  if (env->RegisterNatives(${JAVA_CLASS}_clazz(env),
                            kMethods${JAVA_CLASS},
                            kMethods${JAVA_CLASS}Size) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_${JAVA_CLASS}_clazz, __FILE__);
+        env, ${JAVA_CLASS}_clazz(env), __FILE__);
     return false;
   }
 """)
@@ -1122,11 +1122,10 @@
 
   def GetCalledByNativeValues(self, called_by_native):
     """Fills in necessary values for the CalledByNative methods."""
+    java_class = called_by_native.java_class_name or self.class_name
     if called_by_native.static or called_by_native.is_constructor:
       first_param_in_declaration = ''
-      first_param_in_call = ('g_%s_clazz' %
-                             (called_by_native.java_class_name or
-                              self.class_name))
+      first_param_in_call = ('%s_clazz(env)' % java_class)
     else:
       first_param_in_declaration = ', jobject obj'
       first_param_in_call = 'obj'
@@ -1160,7 +1159,7 @@
       else:
         return_clause = 'return ret;'
     return {
-        'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
+        'JAVA_CLASS': java_class,
         'RETURN_TYPE': return_type,
         'OPTIONAL_ERROR_RETURN': optional_error_return,
         'RETURN_DECLARATION': return_declaration,
@@ -1204,7 +1203,7 @@
 ${FUNCTION_HEADER}
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, ${FIRST_PARAM_IN_CALL},
-      g_${JAVA_CLASS}_clazz${OPTIONAL_ERROR_RETURN});
+      ${JAVA_CLASS}_clazz(env)${OPTIONAL_ERROR_RETURN});
   jmethodID method_id =
     ${GET_METHOD_ID_IMPL}
   ${RETURN_DECLARATION}
@@ -1263,22 +1262,42 @@
       }
       ret += [template.substitute(values)]
     ret += ''
-    for clazz in called_by_native_classes:
+
+    class_getter_methods = []
+    if self.options.native_exports:
       template = Template("""\
 // Leaking this jclass as we cannot use LazyInstance from some threads.
-jclass g_${JAVA_CLASS}_clazz = NULL;""")
+base::subtle::AtomicWord g_${JAVA_CLASS}_clazz = 0;
+#define ${JAVA_CLASS}_clazz(env) \
+base::android::LazyGetClass(env, k${JAVA_CLASS}ClassPath, \
+&g_${JAVA_CLASS}_clazz)""")
+    else:
+      template = Template("""\
+// Leaking this jclass as we cannot use LazyInstance from some threads.
+jclass g_${JAVA_CLASS}_clazz = NULL;
+#define ${JAVA_CLASS}_clazz(env) g_${JAVA_CLASS}_clazz""")
+
+    for clazz in called_by_native_classes:
       values = {
           'JAVA_CLASS': clazz,
       }
       ret += [template.substitute(values)]
+
     return '\n'.join(ret)
 
   def GetFindClasses(self):
     """Returns the imlementation of FindClass for all known classes."""
     if self.init_native:
-      template = Template("""\
+      if self.options.native_exports:
+        template = Template("""\
+    base::subtle::Release_Store(&g_${JAVA_CLASS}_clazz,
+      static_cast<base::subtle::AtomicWord>(env->NewWeakGlobalRef(clazz));""")
+      else:
+        template = Template("""\
   g_${JAVA_CLASS}_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));""")
     else:
+      if self.options.native_exports:
+        return '\n'
       template = Template("""\
   g_${JAVA_CLASS}_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
       base::android::GetClass(env, k${JAVA_CLASS}ClassPath).obj()));""")
@@ -1293,13 +1312,13 @@
     if self.options.eager_called_by_natives:
       template = Template("""\
 env->Get${STATIC_METHOD_PART}MethodID(
-      g_${JAVA_CLASS}_clazz,
+      ${JAVA_CLASS}_clazz(env),
       "${JNI_NAME}", ${JNI_SIGNATURE});""")
     else:
       template = Template("""\
   base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_${STATIC}>(
-      env, g_${JAVA_CLASS}_clazz,
+      env, ${JAVA_CLASS}_clazz(env),
       "${JNI_NAME}",
       ${JNI_SIGNATURE},
       &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME});
diff --git a/base/android/jni_generator/testCalledByNatives.golden b/base/android/jni_generator/testCalledByNatives.golden
index abdc507..22aa45d 100644
--- a/base/android/jni_generator/testCalledByNatives.golden
+++ b/base/android/jni_generator/testCalledByNatives.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -22,8 +22,10 @@
 const char kInfoBarClassPath[] = "org/chromium/TestJni$InfoBar";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_TestJni_clazz = NULL;
+#define TestJni_clazz(env) g_TestJni_clazz
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_InfoBar_clazz = NULL;
+#define InfoBar_clazz(env) g_InfoBar_clazz
 
 }  // namespace
 
@@ -39,11 +41,11 @@
     jobject icon) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "showConfirmInfoBar",
 
 "("
@@ -73,11 +75,11 @@
     jstring args) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "showAutoLoginInfoBar",
 
 "("
@@ -100,11 +102,11 @@
 static void Java_InfoBar_dismiss(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InfoBar_clazz);
+      InfoBar_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InfoBar_clazz,
+      env, InfoBar_clazz(env),
       "dismiss",
 
 "("
@@ -124,12 +126,12 @@
     jstring account,
     jstring args) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_TestJni_clazz,
-      g_TestJni_clazz, false);
+  CHECK_CLAZZ(env, TestJni_clazz(env),
+      TestJni_clazz(env), false);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "shouldShowAutoLogin",
 
 "("
@@ -142,7 +144,7 @@
       &g_TestJni_shouldShowAutoLogin);
 
   jboolean ret =
-      env->CallStaticBooleanMethod(g_TestJni_clazz,
+      env->CallStaticBooleanMethod(TestJni_clazz(env),
           method_id, view, realm, account, args);
   jni_generator::CheckException(env);
   return ret;
@@ -152,12 +154,12 @@
 static base::android::ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv*
     env, jstring url) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_TestJni_clazz,
-      g_TestJni_clazz, NULL);
+  CHECK_CLAZZ(env, TestJni_clazz(env),
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "openUrl",
 
 "("
@@ -167,7 +169,7 @@
       &g_TestJni_openUrl);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_TestJni_clazz,
+      env->CallStaticObjectMethod(TestJni_clazz(env),
           method_id, url);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
@@ -182,11 +184,11 @@
     JniIntWrapper iSecondaryID) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz);
+      TestJni_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "activateHardwareAcceleration",
 
 "("
@@ -211,11 +213,11 @@
     iParam) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz);
+      TestJni_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "uncheckedCall",
 
 "("
@@ -234,11 +236,11 @@
     Java_TestJni_returnByteArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnByteArray",
 
 "("
@@ -258,11 +260,11 @@
     Java_TestJni_returnBooleanArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnBooleanArray",
 
 "("
@@ -282,11 +284,11 @@
     Java_TestJni_returnCharArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnCharArray",
 
 "("
@@ -306,11 +308,11 @@
     Java_TestJni_returnShortArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnShortArray",
 
 "("
@@ -330,11 +332,11 @@
     Java_TestJni_returnIntArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnIntArray",
 
 "("
@@ -354,11 +356,11 @@
     Java_TestJni_returnLongArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnLongArray",
 
 "("
@@ -378,11 +380,11 @@
     Java_TestJni_returnDoubleArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnDoubleArray",
 
 "("
@@ -402,11 +404,11 @@
     Java_TestJni_returnObjectArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnObjectArray",
 
 "("
@@ -426,11 +428,11 @@
     Java_TestJni_returnArrayOfByteArray(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "returnArrayOfByteArray",
 
 "("
@@ -450,11 +452,11 @@
     Java_TestJni_getCompressFormat(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "getCompressFormat",
 
 "("
@@ -474,11 +476,11 @@
     Java_TestJni_getCompressFormatList(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_TestJni_clazz, NULL);
+      TestJni_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_TestJni_clazz,
+      env, TestJni_clazz(env),
       "getCompressFormatList",
 
 "("
diff --git a/base/android/jni_generator/testConstantsFromJavaP.golden b/base/android/jni_generator/testConstantsFromJavaP.golden
index 795bd54..f122529 100644
--- a/base/android/jni_generator/testConstantsFromJavaP.golden
+++ b/base/android/jni_generator/testConstantsFromJavaP.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kMotionEventClassPath[] = "android/view/MotionEvent";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_MotionEvent_clazz = NULL;
+#define MotionEvent_clazz(env) g_MotionEvent_clazz
 
 }  // namespace
 
@@ -117,11 +118,11 @@
 static void Java_MotionEvent_finalize(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "finalize",
       "()V",
       &g_MotionEvent_finalize);
@@ -167,18 +168,18 @@
     JniIntWrapper p12,
     JniIntWrapper p13) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtain",
 "(JJII[Landroid/view/MotionEvent$PointerProperties;[Landroid/view/MotionEvent$PointerCoords;IIFFIIII)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainAVME_J_J_I_I_LAVMEPP_LAVMEPC_I_I_F_F_I_I_I_I);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0, p1, as_jint(p2), as_jint(p3), p4, p5, as_jint(p6),
               as_jint(p7), p8, p9, as_jint(p10), as_jint(p11), as_jint(p12),
               as_jint(p13));
@@ -219,18 +220,18 @@
     JniIntWrapper p11,
     JniIntWrapper p12) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtain",
 "(JJII[I[Landroid/view/MotionEvent$PointerCoords;IFFIIII)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainAVME_J_J_I_I_AI_LAVMEPC_I_F_F_I_I_I_I);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0, p1, as_jint(p2), as_jint(p3), p4, p5, as_jint(p6), p7,
               p8, as_jint(p9), as_jint(p10), as_jint(p11), as_jint(p12));
   jni_generator::CheckException(env);
@@ -266,18 +267,18 @@
     JniIntWrapper p10,
     JniIntWrapper p11) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtain",
       "(JJIFFFFIFFII)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainAVME_J_J_I_F_F_F_F_I_F_F_I_I);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0, p1, as_jint(p2), p3, p4, p5, p6, as_jint(p7), p8, p9,
               as_jint(p10), as_jint(p11));
   jni_generator::CheckException(env);
@@ -315,18 +316,18 @@
     JniIntWrapper p11,
     JniIntWrapper p12) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtain",
       "(JJIIFFFFIFFII)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainAVME_J_J_I_I_F_F_F_F_I_F_F_I_I);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0, p1, as_jint(p2), as_jint(p3), p4, p5, p6, p7,
               as_jint(p8), p9, p10, as_jint(p11), as_jint(p12));
   jni_generator::CheckException(env);
@@ -349,18 +350,18 @@
     jfloat p4,
     JniIntWrapper p5) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtain",
       "(JJIFFI)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainAVME_J_J_I_F_F_I);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0, p1, as_jint(p2), p3, p4, as_jint(p5));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
@@ -373,18 +374,18 @@
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainAVME_AVME(JNIEnv* env, jobject p0) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtain",
       "(Landroid/view/MotionEvent;)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainAVME_AVME);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
@@ -397,18 +398,18 @@
 static base::android::ScopedJavaLocalRef<jobject>
     Java_MotionEvent_obtainNoHistory(JNIEnv* env, jobject p0) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "obtainNoHistory",
       "(Landroid/view/MotionEvent;)Landroid/view/MotionEvent;",
       &g_MotionEvent_obtainNoHistory);
 
   jobject ret =
-      env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, p0);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
@@ -420,11 +421,11 @@
 static void Java_MotionEvent_recycle(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "recycle",
       "()V",
       &g_MotionEvent_recycle);
@@ -441,11 +442,11 @@
 static jint Java_MotionEvent_getDeviceId(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getDeviceId",
       "()I",
       &g_MotionEvent_getDeviceId);
@@ -463,11 +464,11 @@
 static jint Java_MotionEvent_getSource(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getSource",
       "()I",
       &g_MotionEvent_getSource);
@@ -486,11 +487,11 @@
     p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "setSource",
       "(I)V",
       &g_MotionEvent_setSource);
@@ -507,11 +508,11 @@
 static jint Java_MotionEvent_getAction(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getAction",
       "()I",
       &g_MotionEvent_getAction);
@@ -529,11 +530,11 @@
 static jint Java_MotionEvent_getActionMasked(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getActionMasked",
       "()I",
       &g_MotionEvent_getActionMasked);
@@ -551,11 +552,11 @@
 static jint Java_MotionEvent_getActionIndex(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getActionIndex",
       "()I",
       &g_MotionEvent_getActionIndex);
@@ -573,11 +574,11 @@
 static jint Java_MotionEvent_getFlags(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getFlags",
       "()I",
       &g_MotionEvent_getFlags);
@@ -595,11 +596,11 @@
 static jlong Java_MotionEvent_getDownTime(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getDownTime",
       "()J",
       &g_MotionEvent_getDownTime);
@@ -617,11 +618,11 @@
 static jlong Java_MotionEvent_getEventTime(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getEventTime",
       "()J",
       &g_MotionEvent_getEventTime);
@@ -639,11 +640,11 @@
 static jfloat Java_MotionEvent_getXF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getX",
       "()F",
       &g_MotionEvent_getXF);
@@ -661,11 +662,11 @@
 static jfloat Java_MotionEvent_getYF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getY",
       "()F",
       &g_MotionEvent_getYF);
@@ -683,11 +684,11 @@
 static jfloat Java_MotionEvent_getPressureF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getPressure",
       "()F",
       &g_MotionEvent_getPressureF);
@@ -705,11 +706,11 @@
 static jfloat Java_MotionEvent_getSizeF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getSize",
       "()F",
       &g_MotionEvent_getSizeF);
@@ -727,11 +728,11 @@
 static jfloat Java_MotionEvent_getTouchMajorF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getTouchMajor",
       "()F",
       &g_MotionEvent_getTouchMajorF);
@@ -749,11 +750,11 @@
 static jfloat Java_MotionEvent_getTouchMinorF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getTouchMinor",
       "()F",
       &g_MotionEvent_getTouchMinorF);
@@ -771,11 +772,11 @@
 static jfloat Java_MotionEvent_getToolMajorF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getToolMajor",
       "()F",
       &g_MotionEvent_getToolMajorF);
@@ -793,11 +794,11 @@
 static jfloat Java_MotionEvent_getToolMinorF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getToolMinor",
       "()F",
       &g_MotionEvent_getToolMinorF);
@@ -815,11 +816,11 @@
 static jfloat Java_MotionEvent_getOrientationF(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getOrientation",
       "()F",
       &g_MotionEvent_getOrientationF);
@@ -838,11 +839,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getAxisValue",
       "(I)F",
       &g_MotionEvent_getAxisValueF_I);
@@ -860,11 +861,11 @@
 static jint Java_MotionEvent_getPointerCount(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getPointerCount",
       "()I",
       &g_MotionEvent_getPointerCount);
@@ -883,11 +884,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getPointerId",
       "(I)I",
       &g_MotionEvent_getPointerId);
@@ -906,11 +907,11 @@
     p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getToolType",
       "(I)I",
       &g_MotionEvent_getToolType);
@@ -929,11 +930,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "findPointerIndex",
       "(I)I",
       &g_MotionEvent_findPointerIndex);
@@ -952,11 +953,11 @@
     p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getX",
       "(I)F",
       &g_MotionEvent_getXF_I);
@@ -975,11 +976,11 @@
     p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getY",
       "(I)F",
       &g_MotionEvent_getYF_I);
@@ -998,11 +999,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getPressure",
       "(I)F",
       &g_MotionEvent_getPressureF_I);
@@ -1021,11 +1022,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getSize",
       "(I)F",
       &g_MotionEvent_getSizeF_I);
@@ -1044,11 +1045,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getTouchMajor",
       "(I)F",
       &g_MotionEvent_getTouchMajorF_I);
@@ -1067,11 +1068,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getTouchMinor",
       "(I)F",
       &g_MotionEvent_getTouchMinorF_I);
@@ -1090,11 +1091,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getToolMajor",
       "(I)F",
       &g_MotionEvent_getToolMajorF_I);
@@ -1113,11 +1114,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getToolMinor",
       "(I)F",
       &g_MotionEvent_getToolMinorF_I);
@@ -1136,11 +1137,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getOrientation",
       "(I)F",
       &g_MotionEvent_getOrientationF_I);
@@ -1161,11 +1162,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getAxisValue",
       "(II)F",
       &g_MotionEvent_getAxisValueF_I_I);
@@ -1186,11 +1187,11 @@
     jobject p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getPointerCoords",
       "(ILandroid/view/MotionEvent$PointerCoords;)V",
       &g_MotionEvent_getPointerCoords);
@@ -1210,11 +1211,11 @@
     jobject p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getPointerProperties",
       "(ILandroid/view/MotionEvent$PointerProperties;)V",
       &g_MotionEvent_getPointerProperties);
@@ -1231,11 +1232,11 @@
 static jint Java_MotionEvent_getMetaState(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getMetaState",
       "()I",
       &g_MotionEvent_getMetaState);
@@ -1253,11 +1254,11 @@
 static jint Java_MotionEvent_getButtonState(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getButtonState",
       "()I",
       &g_MotionEvent_getButtonState);
@@ -1275,11 +1276,11 @@
 static jfloat Java_MotionEvent_getRawX(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getRawX",
       "()F",
       &g_MotionEvent_getRawX);
@@ -1297,11 +1298,11 @@
 static jfloat Java_MotionEvent_getRawY(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getRawY",
       "()F",
       &g_MotionEvent_getRawY);
@@ -1319,11 +1320,11 @@
 static jfloat Java_MotionEvent_getXPrecision(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getXPrecision",
       "()F",
       &g_MotionEvent_getXPrecision);
@@ -1341,11 +1342,11 @@
 static jfloat Java_MotionEvent_getYPrecision(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getYPrecision",
       "()F",
       &g_MotionEvent_getYPrecision);
@@ -1363,11 +1364,11 @@
 static jint Java_MotionEvent_getHistorySize(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistorySize",
       "()I",
       &g_MotionEvent_getHistorySize);
@@ -1386,11 +1387,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalEventTime",
       "(I)J",
       &g_MotionEvent_getHistoricalEventTime);
@@ -1409,11 +1410,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalX",
       "(I)F",
       &g_MotionEvent_getHistoricalXF_I);
@@ -1432,11 +1433,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalY",
       "(I)F",
       &g_MotionEvent_getHistoricalYF_I);
@@ -1455,11 +1456,11 @@
     obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalPressure",
       "(I)F",
       &g_MotionEvent_getHistoricalPressureF_I);
@@ -1478,11 +1479,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalSize",
       "(I)F",
       &g_MotionEvent_getHistoricalSizeF_I);
@@ -1501,11 +1502,11 @@
     obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalTouchMajor",
       "(I)F",
       &g_MotionEvent_getHistoricalTouchMajorF_I);
@@ -1524,11 +1525,11 @@
     obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalTouchMinor",
       "(I)F",
       &g_MotionEvent_getHistoricalTouchMinorF_I);
@@ -1547,11 +1548,11 @@
     obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalToolMajor",
       "(I)F",
       &g_MotionEvent_getHistoricalToolMajorF_I);
@@ -1570,11 +1571,11 @@
     obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalToolMinor",
       "(I)F",
       &g_MotionEvent_getHistoricalToolMinorF_I);
@@ -1593,11 +1594,11 @@
     obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalOrientation",
       "(I)F",
       &g_MotionEvent_getHistoricalOrientationF_I);
@@ -1618,11 +1619,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalAxisValue",
       "(II)F",
       &g_MotionEvent_getHistoricalAxisValueF_I_I);
@@ -1643,11 +1644,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalX",
       "(II)F",
       &g_MotionEvent_getHistoricalXF_I_I);
@@ -1668,11 +1669,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalY",
       "(II)F",
       &g_MotionEvent_getHistoricalYF_I_I);
@@ -1693,11 +1694,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalPressure",
       "(II)F",
       &g_MotionEvent_getHistoricalPressureF_I_I);
@@ -1718,11 +1719,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalSize",
       "(II)F",
       &g_MotionEvent_getHistoricalSizeF_I_I);
@@ -1743,11 +1744,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalTouchMajor",
       "(II)F",
       &g_MotionEvent_getHistoricalTouchMajorF_I_I);
@@ -1768,11 +1769,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalTouchMinor",
       "(II)F",
       &g_MotionEvent_getHistoricalTouchMinorF_I_I);
@@ -1793,11 +1794,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalToolMajor",
       "(II)F",
       &g_MotionEvent_getHistoricalToolMajorF_I_I);
@@ -1818,11 +1819,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalToolMinor",
       "(II)F",
       &g_MotionEvent_getHistoricalToolMinorF_I_I);
@@ -1843,11 +1844,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalOrientation",
       "(II)F",
       &g_MotionEvent_getHistoricalOrientationF_I_I);
@@ -1870,11 +1871,11 @@
     JniIntWrapper p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalAxisValue",
       "(III)F",
       &g_MotionEvent_getHistoricalAxisValueF_I_I_I);
@@ -1897,11 +1898,11 @@
     jobject p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getHistoricalPointerCoords",
       "(IILandroid/view/MotionEvent$PointerCoords;)V",
       &g_MotionEvent_getHistoricalPointerCoords);
@@ -1918,11 +1919,11 @@
 static jint Java_MotionEvent_getEdgeFlags(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, 0);
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "getEdgeFlags",
       "()I",
       &g_MotionEvent_getEdgeFlags);
@@ -1941,11 +1942,11 @@
     JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "setEdgeFlags",
       "(I)V",
       &g_MotionEvent_setEdgeFlags);
@@ -1963,11 +1964,11 @@
     p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "setAction",
       "(I)V",
       &g_MotionEvent_setAction);
@@ -1985,11 +1986,11 @@
     jfloat p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "offsetLocation",
       "(FF)V",
       &g_MotionEvent_offsetLocation);
@@ -2007,11 +2008,11 @@
     jfloat p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "setLocation",
       "(FF)V",
       &g_MotionEvent_setLocation);
@@ -2028,11 +2029,11 @@
 static void Java_MotionEvent_transform(JNIEnv* env, jobject obj, jobject p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "transform",
       "(Landroid/graphics/Matrix;)V",
       &g_MotionEvent_transform);
@@ -2060,11 +2061,11 @@
     JniIntWrapper p5) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "addBatch",
       "(JFFFFI)V",
       &g_MotionEvent_addBatchV_J_F_F_F_F_I);
@@ -2086,11 +2087,11 @@
     JniIntWrapper p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "addBatch",
       "(J[Landroid/view/MotionEvent$PointerCoords;I)V",
       &g_MotionEvent_addBatchV_J_LAVMEPC_I);
@@ -2109,11 +2110,11 @@
     Java_MotionEvent_toString(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz, NULL);
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "toString",
       "()Ljava/lang/String;",
       &g_MotionEvent_toString);
@@ -2132,18 +2133,18 @@
 static base::android::ScopedJavaLocalRef<jstring>
     Java_MotionEvent_actionToString(JNIEnv* env, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "actionToString",
       "(I)Ljava/lang/String;",
       &g_MotionEvent_actionToString);
 
   jstring ret =
-      static_cast<jstring>(env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      static_cast<jstring>(env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, as_jint(p0)));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jstring>(env, ret);
@@ -2156,18 +2157,18 @@
 static base::android::ScopedJavaLocalRef<jstring>
     Java_MotionEvent_axisToString(JNIEnv* env, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, NULL);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "axisToString",
       "(I)Ljava/lang/String;",
       &g_MotionEvent_axisToString);
 
   jstring ret =
-      static_cast<jstring>(env->CallStaticObjectMethod(g_MotionEvent_clazz,
+      static_cast<jstring>(env->CallStaticObjectMethod(MotionEvent_clazz(env),
           method_id, as_jint(p0)));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jstring>(env, ret);
@@ -2178,18 +2179,18 @@
     __attribute__ ((unused));
 static jint Java_MotionEvent_axisFromString(JNIEnv* env, jstring p0) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_MotionEvent_clazz,
-      g_MotionEvent_clazz, 0);
+  CHECK_CLAZZ(env, MotionEvent_clazz(env),
+      MotionEvent_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "axisFromString",
       "(Ljava/lang/String;)I",
       &g_MotionEvent_axisFromString);
 
   jint ret =
-      env->CallStaticIntMethod(g_MotionEvent_clazz,
+      env->CallStaticIntMethod(MotionEvent_clazz(env),
           method_id, p0);
   jni_generator::CheckException(env);
   return ret;
@@ -2202,11 +2203,11 @@
     JniIntWrapper p1) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_MotionEvent_clazz);
+      MotionEvent_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_MotionEvent_clazz,
+      env, MotionEvent_clazz(env),
       "writeToParcel",
       "(Landroid/os/Parcel;I)V",
       &g_MotionEvent_writeToParcel);
diff --git a/base/android/jni_generator/testEagerCalledByNativesOption.golden b/base/android/jni_generator/testEagerCalledByNativesOption.golden
index 4ff81ac..6c1323e 100644
--- a/base/android/jni_generator/testEagerCalledByNativesOption.golden
+++ b/base/android/jni_generator/testEagerCalledByNativesOption.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kTestClassPath[] = "org/chromium/example/jni_generator/Test";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_Test_clazz = NULL;
+#define Test_clazz(env) g_Test_clazz
 jmethodID g_Test_testMethodWithParam = NULL;
 jmethodID g_Test_testStaticMethodWithParam = NULL;
 jmethodID g_Test_testMethodWithNoParam = NULL;
@@ -46,20 +47,21 @@
 }
 
 static jint testStaticMethodWithParam(JNIEnv* env, JniIntWrapper iParam) {
-  jint ret = env->CallStaticIntMethod(g_Test_clazz,
+  jint ret = env->CallStaticIntMethod(Test_clazz(env),
       g_Test_testStaticMethodWithParam, as_jint(iParam));
   return ret;
 }
 
 static jdouble testMethodWithNoParam(JNIEnv* env) {
-  jdouble ret = env->CallStaticDoubleMethod(g_Test_clazz,
+  jdouble ret = env->CallStaticDoubleMethod(Test_clazz(env),
       g_Test_testMethodWithNoParam);
   return ret;
 }
 
 static base::android::ScopedJavaLocalRef<jstring>
     testStaticMethodWithNoParam(JNIEnv* env) {
-  jstring ret = static_cast<jstring>(env->CallStaticObjectMethod(g_Test_clazz,
+  jstring ret =
+      static_cast<jstring>(env->CallStaticObjectMethod(Test_clazz(env),
       g_Test_testStaticMethodWithNoParam));
   return base::android::ScopedJavaLocalRef<jstring>(env, ret);
 }
@@ -81,16 +83,16 @@
 
   const int kMethodsTestSize = arraysize(kMethodsTest);
 
-  if (env->RegisterNatives(g_Test_clazz,
+  if (env->RegisterNatives(Test_clazz(env),
                            kMethodsTest,
                            kMethodsTestSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_Test_clazz, __FILE__);
+        env, Test_clazz(env), __FILE__);
     return false;
   }
 
   g_Test_testMethodWithParam = env->GetMethodID(
-      g_Test_clazz,
+      Test_clazz(env),
       "testMethodWithParam",
 "("
 "I"
@@ -101,7 +103,7 @@
   }
 
   g_Test_testStaticMethodWithParam = env->GetStaticMethodID(
-      g_Test_clazz,
+      Test_clazz(env),
       "testStaticMethodWithParam",
 "("
 "I"
@@ -112,7 +114,7 @@
   }
 
   g_Test_testMethodWithNoParam = env->GetStaticMethodID(
-      g_Test_clazz,
+      Test_clazz(env),
       "testMethodWithNoParam",
 "("
 ")"
@@ -122,7 +124,7 @@
   }
 
   g_Test_testStaticMethodWithNoParam = env->GetStaticMethodID(
-      g_Test_clazz,
+      Test_clazz(env),
       "testStaticMethodWithNoParam",
 "("
 ")"
diff --git a/base/android/jni_generator/testFromJavaP.golden b/base/android/jni_generator/testFromJavaP.golden
index 34e2118..5827410 100644
--- a/base/android/jni_generator/testFromJavaP.golden
+++ b/base/android/jni_generator/testFromJavaP.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kInputStreamClassPath[] = "java/io/InputStream";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_InputStream_clazz = NULL;
+#define InputStream_clazz(env) g_InputStream_clazz
 
 }  // namespace
 
@@ -34,11 +35,11 @@
 static jint Java_InputStream_available(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz, 0);
+      InputStream_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "available",
       "()I",
       &g_InputStream_available);
@@ -56,11 +57,11 @@
 static void Java_InputStream_close(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz);
+      InputStream_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "close",
       "()V",
       &g_InputStream_close);
@@ -77,11 +78,11 @@
 static void Java_InputStream_mark(JNIEnv* env, jobject obj, JniIntWrapper p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz);
+      InputStream_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "mark",
       "(I)V",
       &g_InputStream_mark);
@@ -98,11 +99,11 @@
 static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz, false);
+      InputStream_clazz(env), false);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "markSupported",
       "()Z",
       &g_InputStream_markSupported);
@@ -120,11 +121,11 @@
 static jint Java_InputStream_readI(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz, 0);
+      InputStream_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "read",
       "()I",
       &g_InputStream_readI);
@@ -142,11 +143,11 @@
 static jint Java_InputStream_readI_AB(JNIEnv* env, jobject obj, jbyteArray p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz, 0);
+      InputStream_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "read",
       "([B)I",
       &g_InputStream_readI_AB);
@@ -169,11 +170,11 @@
     JniIntWrapper p2) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz, 0);
+      InputStream_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "read",
       "([BII)I",
       &g_InputStream_readI_AB_I_I);
@@ -191,11 +192,11 @@
 static void Java_InputStream_reset(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz);
+      InputStream_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "reset",
       "()V",
       &g_InputStream_reset);
@@ -212,11 +213,11 @@
 static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_InputStream_clazz, 0);
+      InputStream_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "skip",
       "(J)J",
       &g_InputStream_skip);
@@ -234,18 +235,18 @@
 static base::android::ScopedJavaLocalRef<jobject>
     Java_InputStream_Constructor(JNIEnv* env) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_InputStream_clazz,
-      g_InputStream_clazz, NULL);
+  CHECK_CLAZZ(env, InputStream_clazz(env),
+      InputStream_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_InputStream_clazz,
+      env, InputStream_clazz(env),
       "<init>",
       "()V",
       &g_InputStream_Constructor);
 
   jobject ret =
-      env->NewObject(g_InputStream_clazz,
+      env->NewObject(InputStream_clazz(env),
           method_id);
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jobject>(env, ret);
diff --git a/base/android/jni_generator/testFromJavaPGenerics.golden b/base/android/jni_generator/testFromJavaPGenerics.golden
index 48582fd..5d78390 100644
--- a/base/android/jni_generator/testFromJavaPGenerics.golden
+++ b/base/android/jni_generator/testFromJavaPGenerics.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kHashSetClassPath[] = "java/util/HashSet";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_HashSet_clazz = NULL;
+#define HashSet_clazz(env) g_HashSet_clazz
 
 }  // namespace
 
@@ -34,11 +35,11 @@
 static void Java_HashSet_dummy(JNIEnv* env, jobject obj) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_HashSet_clazz);
+      HashSet_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_HashSet_clazz,
+      env, HashSet_clazz(env),
       "dummy",
       "()V",
       &g_HashSet_dummy);
diff --git a/base/android/jni_generator/testInnerClassNatives.golden b/base/android/jni_generator/testInnerClassNatives.golden
index 56a2e9b..2dee84e 100644
--- a/base/android/jni_generator/testInnerClassNatives.golden
+++ b/base/android/jni_generator/testInnerClassNatives.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -22,6 +22,7 @@
 const char kMyInnerClassClassPath[] = "org/chromium/TestJni$MyInnerClass";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_TestJni_clazz = NULL;
+#define TestJni_clazz(env) g_TestJni_clazz
 
 }  // namespace
 
@@ -44,11 +45,11 @@
 
   const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);
 
-  if (env->RegisterNatives(g_MyInnerClass_clazz,
+  if (env->RegisterNatives(MyInnerClass_clazz(env),
                            kMethodsMyInnerClass,
                            kMethodsMyInnerClassSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_MyInnerClass_clazz, __FILE__);
+        env, MyInnerClass_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
index 07b857f..6ffbaac 100644
--- a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
+++ b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -23,6 +23,7 @@
 const char kTestJniClassPath[] = "org/chromium/TestJni";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_TestJni_clazz = NULL;
+#define TestJni_clazz(env) g_TestJni_clazz
 
 }  // namespace
 
@@ -55,21 +56,21 @@
   const int kMethodsMyOtherInnerClassSize =
       arraysize(kMethodsMyOtherInnerClass);
 
-  if (env->RegisterNatives(g_MyOtherInnerClass_clazz,
+  if (env->RegisterNatives(MyOtherInnerClass_clazz(env),
                            kMethodsMyOtherInnerClass,
                            kMethodsMyOtherInnerClassSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_MyOtherInnerClass_clazz, __FILE__);
+        env, MyOtherInnerClass_clazz(env), __FILE__);
     return false;
   }
 
   const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
 
-  if (env->RegisterNatives(g_TestJni_clazz,
+  if (env->RegisterNatives(TestJni_clazz(env),
                            kMethodsTestJni,
                            kMethodsTestJniSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_TestJni_clazz, __FILE__);
+        env, TestJni_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testInnerClassNativesMultiple.golden b/base/android/jni_generator/testInnerClassNativesMultiple.golden
index 6a7f04d..b74e65f 100644
--- a/base/android/jni_generator/testInnerClassNativesMultiple.golden
+++ b/base/android/jni_generator/testInnerClassNativesMultiple.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -24,6 +24,7 @@
 const char kMyInnerClassClassPath[] = "org/chromium/TestJni$MyInnerClass";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_TestJni_clazz = NULL;
+#define TestJni_clazz(env) g_TestJni_clazz
 
 }  // namespace
 
@@ -56,21 +57,21 @@
   const int kMethodsMyOtherInnerClassSize =
       arraysize(kMethodsMyOtherInnerClass);
 
-  if (env->RegisterNatives(g_MyOtherInnerClass_clazz,
+  if (env->RegisterNatives(MyOtherInnerClass_clazz(env),
                            kMethodsMyOtherInnerClass,
                            kMethodsMyOtherInnerClassSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_MyOtherInnerClass_clazz, __FILE__);
+        env, MyOtherInnerClass_clazz(env), __FILE__);
     return false;
   }
 
   const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);
 
-  if (env->RegisterNatives(g_MyInnerClass_clazz,
+  if (env->RegisterNatives(MyInnerClass_clazz(env),
                            kMethodsMyInnerClass,
                            kMethodsMyInnerClassSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_MyInnerClass_clazz, __FILE__);
+        env, MyInnerClass_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testJNIInitNativeNameOption.golden b/base/android/jni_generator/testJNIInitNativeNameOption.golden
index 0d5d3c6..53b5f17 100644
--- a/base/android/jni_generator/testJNIInitNativeNameOption.golden
+++ b/base/android/jni_generator/testJNIInitNativeNameOption.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kTestClassPath[] = "org/chromium/example/jni_generator/Test";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_Test_clazz = NULL;
+#define Test_clazz(env) g_Test_clazz
 
 }  // namespace
 
@@ -49,11 +50,11 @@
 
   const int kMethodsTestSize = arraysize(kMethodsTest);
 
-  if (env->RegisterNatives(g_Test_clazz,
+  if (env->RegisterNatives(Test_clazz(env),
                            kMethodsTest,
                            kMethodsTestSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_Test_clazz, __FILE__);
+        env, Test_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testJarJarRemapping.golden b/base/android/jni_generator/testJarJarRemapping.golden
index 9b2c0b3..75a35c5 100644
--- a/base/android/jni_generator/testJarJarRemapping.golden
+++ b/base/android/jni_generator/testJarJarRemapping.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kExampleClassPath[] = "com/test/jni_generator/Example";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_Example_clazz = NULL;
+#define Example_clazz(env) g_Example_clazz
 
 }  // namespace
 
@@ -69,11 +70,11 @@
 
   const int kMethodsExampleSize = arraysize(kMethodsExample);
 
-  if (env->RegisterNatives(g_Example_clazz,
+  if (env->RegisterNatives(Example_clazz(env),
                            kMethodsExample,
                            kMethodsExampleSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_Example_clazz, __FILE__);
+        env, Example_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
index 9cc1256..df5b1c8 100644
--- a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
+++ b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kFooClassPath[] = "org/chromium/foo/Foo";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_Foo_clazz = NULL;
+#define Foo_clazz(env) g_Foo_clazz
 
 }  // namespace
 
@@ -34,12 +35,12 @@
 static void Java_Foo_calledByNative(JNIEnv* env, jobject callback1,
     jobject callback2) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_Foo_clazz,
-      g_Foo_clazz);
+  CHECK_CLAZZ(env, Foo_clazz(env),
+      Foo_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_Foo_clazz,
+      env, Foo_clazz(env),
       "calledByNative",
 
 "("
@@ -49,7 +50,7 @@
 "V",
       &g_Foo_calledByNative);
 
-     env->CallStaticVoidMethod(g_Foo_clazz,
+     env->CallStaticVoidMethod(Foo_clazz(env),
           method_id, callback1, callback2);
   jni_generator::CheckException(env);
 
@@ -72,11 +73,11 @@
 
   const int kMethodsFooSize = arraysize(kMethodsFoo);
 
-  if (env->RegisterNatives(g_Foo_clazz,
+  if (env->RegisterNatives(Foo_clazz(env),
                            kMethodsFoo,
                            kMethodsFooSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_Foo_clazz, __FILE__);
+        env, Foo_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testNativeExportsOption.golden b/base/android/jni_generator/testNativeExportsOption.golden
index 231be7c..5beaa82 100644
--- a/base/android/jni_generator/testNativeExportsOption.golden
+++ b/base/android/jni_generator/testNativeExportsOption.golden
@@ -21,7 +21,8 @@
 const char kSampleForTestsClassPath[] =
     "org/chromium/example/jni_generator/SampleForTests";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
-jclass g_SampleForTests_clazz = NULL;
+base::subtle::AtomicWord g_SampleForTests_clazz = 0;
+#define SampleForTests_clazz(env) base::android::LazyGetClass(env, kSampleForTestsClassPath, &g_SampleForTests_clazz)
 
 }  // namespace
 
@@ -79,11 +80,11 @@
     JniIntWrapper iParam) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz);
+      SampleForTests_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "testMethodWithParam",
 
 "("
@@ -105,11 +106,11 @@
     JniIntWrapper iParam) {
   /* Must call RegisterNativesImpl()  */
   CHECK_CLAZZ(env, obj,
-      g_SampleForTests_clazz, NULL);
+      SampleForTests_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_INSTANCE>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "testMethodWithParamAndReturn",
 
 "("
@@ -129,12 +130,12 @@
 static jint Java_SampleForTests_testStaticMethodWithParam(JNIEnv* env,
     JniIntWrapper iParam) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_SampleForTests_clazz,
-      g_SampleForTests_clazz, 0);
+  CHECK_CLAZZ(env, SampleForTests_clazz(env),
+      SampleForTests_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "testStaticMethodWithParam",
 
 "("
@@ -144,7 +145,7 @@
       &g_SampleForTests_testStaticMethodWithParam);
 
   jint ret =
-      env->CallStaticIntMethod(g_SampleForTests_clazz,
+      env->CallStaticIntMethod(SampleForTests_clazz(env),
           method_id, as_jint(iParam));
   jni_generator::CheckException(env);
   return ret;
@@ -153,12 +154,12 @@
 static base::subtle::AtomicWord g_SampleForTests_testMethodWithNoParam = 0;
 static jdouble Java_SampleForTests_testMethodWithNoParam(JNIEnv* env) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_SampleForTests_clazz,
-      g_SampleForTests_clazz, 0);
+  CHECK_CLAZZ(env, SampleForTests_clazz(env),
+      SampleForTests_clazz(env), 0);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "testMethodWithNoParam",
 
 "("
@@ -167,7 +168,7 @@
       &g_SampleForTests_testMethodWithNoParam);
 
   jdouble ret =
-      env->CallStaticDoubleMethod(g_SampleForTests_clazz,
+      env->CallStaticDoubleMethod(SampleForTests_clazz(env),
           method_id);
   jni_generator::CheckException(env);
   return ret;
@@ -178,12 +179,12 @@
 static base::android::ScopedJavaLocalRef<jstring>
     Java_SampleForTests_testStaticMethodWithNoParam(JNIEnv* env) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_SampleForTests_clazz,
-      g_SampleForTests_clazz, NULL);
+  CHECK_CLAZZ(env, SampleForTests_clazz(env),
+      SampleForTests_clazz(env), NULL);
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_SampleForTests_clazz,
+      env, SampleForTests_clazz(env),
       "testStaticMethodWithNoParam",
 
 "("
@@ -192,7 +193,7 @@
       &g_SampleForTests_testStaticMethodWithNoParam);
 
   jstring ret =
-      static_cast<jstring>(env->CallStaticObjectMethod(g_SampleForTests_clazz,
+static_cast<jstring>(env->CallStaticObjectMethod(SampleForTests_clazz(env),
           method_id));
   jni_generator::CheckException(env);
   return base::android::ScopedJavaLocalRef<jstring>(env, ret);
@@ -202,7 +203,8 @@
 // Step 3: RegisterNatives.
 
 static bool RegisterNativesImpl(JNIEnv* env, jclass clazz) {
-  g_SampleForTests_clazz = static_cast<jclass>(env->NewWeakGlobalRef(clazz));
+    base::subtle::Release_Store(&g_SampleForTests_clazz,
+      static_cast<base::subtle::AtomicWord>(env->NewWeakGlobalRef(clazz));
 
   return true;
 }
diff --git a/base/android/jni_generator/testNatives.golden b/base/android/jni_generator/testNatives.golden
index db69a5a..8708fa2 100644
--- a/base/android/jni_generator/testNatives.golden
+++ b/base/android/jni_generator/testNatives.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kTestJniClassPath[] = "org/chromium/TestJni";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_TestJni_clazz = NULL;
+#define TestJni_clazz(env) g_TestJni_clazz
 
 }  // namespace
 
@@ -202,11 +203,11 @@
 
   const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
 
-  if (env->RegisterNatives(g_TestJni_clazz,
+  if (env->RegisterNatives(TestJni_clazz(env),
                            kMethodsTestJni,
                            kMethodsTestJniSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_TestJni_clazz, __FILE__);
+        env, TestJni_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testNativesLong.golden b/base/android/jni_generator/testNativesLong.golden
index 25b5fad..11e7c49 100644
--- a/base/android/jni_generator/testNativesLong.golden
+++ b/base/android/jni_generator/testNativesLong.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kTestJniClassPath[] = "org/chromium/TestJni";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_TestJni_clazz = NULL;
+#define TestJni_clazz(env) g_TestJni_clazz
 
 }  // namespace
 
@@ -49,11 +50,11 @@
 
   const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
 
-  if (env->RegisterNatives(g_TestJni_clazz,
+  if (env->RegisterNatives(TestJni_clazz(env),
                            kMethodsTestJni,
                            kMethodsTestJniSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_TestJni_clazz, __FILE__);
+        env, TestJni_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testPureNativeMethodsOption.golden b/base/android/jni_generator/testPureNativeMethodsOption.golden
index 8d9ee9e..a45a386 100644
--- a/base/android/jni_generator/testPureNativeMethodsOption.golden
+++ b/base/android/jni_generator/testPureNativeMethodsOption.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kTestClassPath[] = "org/chromium/example/jni_generator/Test";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_Test_clazz = NULL;
+#define Test_clazz(env) g_Test_clazz
 
 }  // namespace
 
@@ -50,11 +51,11 @@
 
   const int kMethodsTestSize = arraysize(kMethodsTest);
 
-  if (env->RegisterNatives(g_Test_clazz,
+  if (env->RegisterNatives(Test_clazz(env),
                            kMethodsTest,
                            kMethodsTestSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_Test_clazz, __FILE__);
+        env, Test_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_generator/testSingleJNIAdditionalImport.golden b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
index e395657..787f7f5 100644
--- a/base/android/jni_generator/testSingleJNIAdditionalImport.golden
+++ b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// 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.
 
@@ -21,6 +21,7 @@
 const char kFooClassPath[] = "org/chromium/foo/Foo";
 // Leaking this jclass as we cannot use LazyInstance from some threads.
 jclass g_Foo_clazz = NULL;
+#define Foo_clazz(env) g_Foo_clazz
 
 }  // namespace
 
@@ -32,12 +33,12 @@
 static base::subtle::AtomicWord g_Foo_calledByNative = 0;
 static void Java_Foo_calledByNative(JNIEnv* env, jobject callback) {
   /* Must call RegisterNativesImpl()  */
-  CHECK_CLAZZ(env, g_Foo_clazz,
-      g_Foo_clazz);
+  CHECK_CLAZZ(env, Foo_clazz(env),
+      Foo_clazz(env));
   jmethodID method_id =
       base::android::MethodID::LazyGet<
       base::android::MethodID::TYPE_STATIC>(
-      env, g_Foo_clazz,
+      env, Foo_clazz(env),
       "calledByNative",
 
 "("
@@ -46,7 +47,7 @@
 "V",
       &g_Foo_calledByNative);
 
-     env->CallStaticVoidMethod(g_Foo_clazz,
+     env->CallStaticVoidMethod(Foo_clazz(env),
           method_id, callback);
   jni_generator::CheckException(env);
 
@@ -68,11 +69,11 @@
 
   const int kMethodsFooSize = arraysize(kMethodsFoo);
 
-  if (env->RegisterNatives(g_Foo_clazz,
+  if (env->RegisterNatives(Foo_clazz(env),
                            kMethodsFoo,
                            kMethodsFooSize) < 0) {
     jni_generator::HandleRegistrationError(
-        env, g_Foo_clazz, __FILE__);
+        env, Foo_clazz(env), __FILE__);
     return false;
   }
 
diff --git a/base/android/jni_utils.cc b/base/android/jni_utils.cc
new file mode 100644
index 0000000..b4d682b
--- /dev/null
+++ b/base/android/jni_utils.cc
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/jni_utils.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/scoped_java_ref.h"
+
+#include "jni/JNIUtils_jni.h"
+
+namespace base {
+namespace android {
+
+ScopedJavaLocalRef<jobject> GetClassLoader(JNIEnv* env) {
+  return Java_JNIUtils_getClassLoader(env);
+}
+
+bool RegisterJNIUtils(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+}  // namespace android
+}  // namespace base
+
diff --git a/base/android/jni_utils.h b/base/android/jni_utils.h
new file mode 100644
index 0000000..b793aed
--- /dev/null
+++ b/base/android/jni_utils.h
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ANDROID_JNI_UTILS_H_
+#define BASE_ANDROID_JNI_UTILS_H_
+
+#include <jni.h>
+
+#include "base/android/scoped_java_ref.h"
+
+namespace base {
+
+namespace android {
+
+// Gets a ClassLoader instance capable of loading Chromium java classes.
+// This should be called either from JNI_OnLoad or from within a method called
+// via JNI from Java.
+BASE_EXPORT ScopedJavaLocalRef<jobject> GetClassLoader(JNIEnv* env);
+
+bool RegisterJNIUtils(JNIEnv* env);
+
+}  // namespace android
+}  // namespace base
+
+#endif  // BASE_ANDROID_JNI_UTILS_H_
+
diff --git a/base/android/linker/linker_jni.cc b/base/android/linker/linker_jni.cc
index b0b464b..d33e6fa 100644
--- a/base/android/linker/linker_jni.cc
+++ b/base/android/linker/linker_jni.cc
@@ -451,7 +451,7 @@
   LOG_INFO("%s: Calling back to java with handler %p, opaque %p",
            __FUNCTION__, callback->handler, callback->opaque);
 
-  jlong arg = static_cast<jlong>(reinterpret_cast<intptr_t>(callback));
+  jlong arg = static_cast<jlong>(reinterpret_cast<uintptr_t>(callback));
   env->CallStaticVoidMethod(
       s_java_callback_bindings.clazz, s_java_callback_bindings.method_id, arg);
 
diff --git a/base/base.gyp b/base/base.gyp
index ee19b8b..d3c397c 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -1282,6 +1282,7 @@
             'android/java/src/org/chromium/base/EventLog.java',
             'android/java/src/org/chromium/base/FieldTrialList.java',
             'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java',
+            'android/java/src/org/chromium/base/JNIUtils.java',
             'android/java/src/org/chromium/base/library_loader/LibraryLoader.java',
             'android/java/src/org/chromium/base/MemoryPressureListener.java',
             'android/java/src/org/chromium/base/JavaHandlerThread.java',
diff --git a/base/base.gypi b/base/base.gypi
index 8a3a56c..cfa9d61 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -55,6 +55,8 @@
           'android/jni_registrar.h',
           'android/jni_string.cc',
           'android/jni_string.h',
+          'android/jni_utils.cc',
+          'android/jni_utils.h',
           'android/jni_weak_ref.cc',
           'android/jni_weak_ref.h',
           'android/library_loader/library_loader_hooks.cc',
diff --git a/base/base.target.darwin-arm.mk b/base/base.target.darwin-arm.mk
index 90b7760..e9557cf 100644
--- a/base/base.target.darwin-arm.mk
+++ b/base/base.target.darwin-arm.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.darwin-arm64.mk b/base/base.target.darwin-arm64.mk
index ef1e083..eab46f9 100644
--- a/base/base.target.darwin-arm64.mk
+++ b/base/base.target.darwin-arm64.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.darwin-mips.mk b/base/base.target.darwin-mips.mk
index b63bc38..f3651ef 100644
--- a/base/base.target.darwin-mips.mk
+++ b/base/base.target.darwin-mips.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.darwin-x86.mk b/base/base.target.darwin-x86.mk
index 34516b4..66dd067 100644
--- a/base/base.target.darwin-x86.mk
+++ b/base/base.target.darwin-x86.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.darwin-x86_64.mk b/base/base.target.darwin-x86_64.mk
index 9045196..81d6428 100644
--- a/base/base.target.darwin-x86_64.mk
+++ b/base/base.target.darwin-x86_64.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.linux-arm.mk b/base/base.target.linux-arm.mk
index 90b7760..e9557cf 100644
--- a/base/base.target.linux-arm.mk
+++ b/base/base.target.linux-arm.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.linux-arm64.mk b/base/base.target.linux-arm64.mk
index ef1e083..eab46f9 100644
--- a/base/base.target.linux-arm64.mk
+++ b/base/base.target.linux-arm64.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.linux-mips.mk b/base/base.target.linux-mips.mk
index b63bc38..f3651ef 100644
--- a/base/base.target.linux-mips.mk
+++ b/base/base.target.linux-mips.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.linux-x86.mk b/base/base.target.linux-x86.mk
index 34516b4..66dd067 100644
--- a/base/base.target.linux-x86.mk
+++ b/base/base.target.linux-x86.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base.target.linux-x86_64.mk b/base/base.target.linux-x86_64.mk
index 9045196..81d6428 100644
--- a/base/base.target.linux-x86_64.mk
+++ b/base/base.target.linux-x86_64.mk
@@ -57,6 +57,7 @@
 	base/android/jni_array.cc \
 	base/android/jni_registrar.cc \
 	base/android/jni_string.cc \
+	base/android/jni_utils.cc \
 	base/android/jni_weak_ref.cc \
 	base/android/library_loader/library_loader_hooks.cc \
 	base/android/memory_pressure_listener_android.cc \
diff --git a/base/base_jni_headers.target.darwin-arm.mk b/base/base_jni_headers.target.darwin-arm.mk
index 0adb114..10b2a3a 100644
--- a/base/base_jni_headers.target.darwin-arm.mk
+++ b/base/base_jni_headers.target.darwin-arm.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.darwin-arm64.mk b/base/base_jni_headers.target.darwin-arm64.mk
index 5bbe2cc..a417e5a 100644
--- a/base/base_jni_headers.target.darwin-arm64.mk
+++ b/base/base_jni_headers.target.darwin-arm64.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.darwin-mips.mk b/base/base_jni_headers.target.darwin-mips.mk
index e98ef31..a6064e1 100644
--- a/base/base_jni_headers.target.darwin-mips.mk
+++ b/base/base_jni_headers.target.darwin-mips.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.darwin-x86.mk b/base/base_jni_headers.target.darwin-x86.mk
index c3de127..be3acd2 100644
--- a/base/base_jni_headers.target.darwin-x86.mk
+++ b/base/base_jni_headers.target.darwin-x86.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.darwin-x86_64.mk b/base/base_jni_headers.target.darwin-x86_64.mk
index d355eaf..d6df8ab 100644
--- a/base/base_jni_headers.target.darwin-x86_64.mk
+++ b/base/base_jni_headers.target.darwin-x86_64.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.linux-arm.mk b/base/base_jni_headers.target.linux-arm.mk
index 0adb114..10b2a3a 100644
--- a/base/base_jni_headers.target.linux-arm.mk
+++ b/base/base_jni_headers.target.linux-arm.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.linux-arm64.mk b/base/base_jni_headers.target.linux-arm64.mk
index 5bbe2cc..a417e5a 100644
--- a/base/base_jni_headers.target.linux-arm64.mk
+++ b/base/base_jni_headers.target.linux-arm64.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.linux-mips.mk b/base/base_jni_headers.target.linux-mips.mk
index e98ef31..a6064e1 100644
--- a/base/base_jni_headers.target.linux-mips.mk
+++ b/base/base_jni_headers.target.linux-mips.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.linux-x86.mk b/base/base_jni_headers.target.linux-x86.mk
index c3de127..be3acd2 100644
--- a/base/base_jni_headers.target.linux-x86.mk
+++ b/base/base_jni_headers.target.linux-x86.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/base_jni_headers.target.linux-x86_64.mk b/base/base_jni_headers.target.linux-x86_64.mk
index d355eaf..d6df8ab 100644
--- a/base/base_jni_headers.target.linux-x86_64.mk
+++ b/base/base_jni_headers.target.linux-x86_64.mk
@@ -17,7 +17,7 @@
 
 
 ### Generated for rule "base_base_gyp_base_jni_headers_target_generate_jni_headers":
-# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
+# "{'inputs': ['../base/android/jni_generator/jni_generator.py', '../android_webview/build/jarjar-rules.txt'], 'process_outputs_as_sources': '1', 'extension': 'java', 'outputs': ['$(gyp_shared_intermediate_dir)/base/jni/%(INPUT_ROOT)s_jni.h'], 'rule_name': 'generate_jni_headers', 'rule_sources': ['android/java/src/org/chromium/base/ApplicationStatus.java', 'android/java/src/org/chromium/base/BuildInfo.java', 'android/java/src/org/chromium/base/CommandLine.java', 'android/java/src/org/chromium/base/ContentUriUtils.java', 'android/java/src/org/chromium/base/CpuFeatures.java', 'android/java/src/org/chromium/base/EventLog.java', 'android/java/src/org/chromium/base/FieldTrialList.java', 'android/java/src/org/chromium/base/ImportantFileWriterAndroid.java', 'android/java/src/org/chromium/base/JNIUtils.java', 'android/java/src/org/chromium/base/library_loader/LibraryLoader.java', 'android/java/src/org/chromium/base/MemoryPressureListener.java', 'android/java/src/org/chromium/base/JavaHandlerThread.java', 'android/java/src/org/chromium/base/PathService.java', 'android/java/src/org/chromium/base/PathUtils.java', 'android/java/src/org/chromium/base/PowerMonitor.java', 'android/java/src/org/chromium/base/SystemMessageHandler.java', 'android/java/src/org/chromium/base/SysUtils.java', 'android/java/src/org/chromium/base/ThreadUtils.java', 'android/java/src/org/chromium/base/TraceEvent.java'], 'action': ['../base/android/jni_generator/jni_generator.py', '--input_file', '$(RULE_SOURCES)', '--output_dir', '$(gyp_shared_intermediate_dir)/base/jni', '--includes', 'base/android/jni_generator/jni_generator_helper.h', '--optimize_generation', '0', '--jarjar', '../android_webview/build/jarjar-rules.txt', '--ptr_type', 'long', '--native_exports'], 'message': 'Generating JNI bindings from $(RULE_SOURCES)'}":
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/ApplicationStatus_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -90,6 +90,15 @@
 	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/ImportantFileWriterAndroid.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
 
 
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h: $(LOCAL_PATH)/base/android/java/src/org/chromium/base/JNIUtils.java $(LOCAL_PATH)/base/android/jni_generator/jni_generator.py $(LOCAL_PATH)/android_webview/build/jarjar-rules.txt $(GYP_TARGET_DEPENDENCIES)
+	mkdir -p $(gyp_shared_intermediate_dir)/base/jni; cd $(gyp_local_path)/base; ../base/android/jni_generator/jni_generator.py --input_file android/java/src/org/chromium/base/JNIUtils.java --output_dir "$(gyp_shared_intermediate_dir)/base/jni" --includes base/android/jni_generator/jni_generator_helper.h --optimize_generation 0 --jarjar ../android_webview/build/jarjar-rules.txt --ptr_type long --native_exports
+
+
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_var_prefix := $(GYP_VAR_PREFIX)
 $(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -190,6 +199,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
@@ -213,6 +223,7 @@
 	$(gyp_shared_intermediate_dir)/base/jni/EventLog_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/FieldTrialList_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/ImportantFileWriterAndroid_jni.h \
+	$(gyp_shared_intermediate_dir)/base/jni/JNIUtils_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/LibraryLoader_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/MemoryPressureListener_jni.h \
 	$(gyp_shared_intermediate_dir)/base/jni/JavaHandlerThread_jni.h \
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index 61b4a6a..fad141f 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -254,4 +254,18 @@
 
 #endif  // MAC_OS_X_VERSION_10_9
 
+#if !defined(MAC_OS_X_VERSION_10_10) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
+
+@interface NSUserActivity : NSObject
+
+@property (readonly, copy) NSString* activityType;
+@property (copy) NSURL* webPageURL;
+
+@end
+
+BASE_EXPORT extern "C" NSString* const NSUserActivityTypeBrowsingWeb;
+
+#endif  // MAC_OS_X_VERSION_10_10
+
 #endif  // BASE_MAC_SDK_FORWARD_DECLARATIONS_H_
diff --git a/base/mac/sdk_forward_declarations.mm b/base/mac/sdk_forward_declarations.mm
index a402a41..22986da 100644
--- a/base/mac/sdk_forward_declarations.mm
+++ b/base/mac/sdk_forward_declarations.mm
@@ -12,3 +12,12 @@
     @"NSWindowWillEnterFullScreenNotification";
 
 #endif  // MAC_OS_X_VERSION_10_7
+
+// Replicate specific 10.10 SDK declarations for building with prior SDKs.
+#if !defined(MAC_OS_X_VERSION_10_10) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
+
+NSString* const NSUserActivityTypeBrowsingWeb =
+    @"NSUserActivityTypeBrowsingWeb";
+
+#endif  // MAC_OS_X_VERSION_10_10
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
index bb6266b..7e6e551 100644
--- a/build/util/LASTCHANGE
+++ b/build/util/LASTCHANGE
@@ -1 +1 @@
-LASTCHANGE=290690
+LASTCHANGE=a4726a104436
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
index 2887aef..0558f2d 100644
--- a/build/util/LASTCHANGE.blink
+++ b/build/util/LASTCHANGE.blink
@@ -1 +1 @@
-LASTCHANGE=180871
+LASTCHANGE=181577
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index e6e60f5..87cb2f8 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -771,7 +771,7 @@
 
 // TODO(wjmaclean) Convert so that bounds returns SizeF.
 gfx::Size LayerImpl::bounds() const {
-  return ToFlooredSize(temporary_impl_bounds_);
+  return ToCeiledSize(temporary_impl_bounds_);
 }
 
 void LayerImpl::SetBounds(const gfx::Size& bounds) {
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 49ad601..c477720 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -264,6 +264,12 @@
   // unused can be considered for removal.
   std::vector<PictureLayerTiling*> seen_tilings;
 
+  // Ignore missing tiles outside of viewport for tile priority. This is
+  // normally the same as draw viewport but can be independently overridden by
+  // embedders like Android WebView with SetExternalDrawConstraints.
+  gfx::Rect scaled_viewport_for_tile_priority = gfx::ScaleToEnclosingRect(
+      GetViewportForTilePriorityInContentSpace(), max_contents_scale);
+
   size_t missing_tile_count = 0u;
   size_t on_demand_missing_tile_count = 0u;
   for (PictureLayerTilingSet::CoverageIterator iter(tilings_.get(),
@@ -281,6 +287,7 @@
     append_quads_data->visible_content_area +=
         visible_geometry_rect.width() * visible_geometry_rect.height();
 
+    bool has_draw_quad = false;
     if (*iter && iter->IsReadyToDraw()) {
       const ManagedTileState::TileVersion& tile_version =
           iter->GetTileVersionForDrawing();
@@ -290,8 +297,10 @@
           gfx::Rect opaque_rect = iter->opaque_rect();
           opaque_rect.Intersect(geometry_rect);
 
-          if (iter->contents_scale() != ideal_contents_scale_)
+          if (iter->contents_scale() != ideal_contents_scale_ &&
+              geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
             append_quads_data->num_incomplete_tiles++;
+          }
 
           TileDrawQuad* quad =
               render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
@@ -303,6 +312,7 @@
                        texture_rect,
                        iter.texture_size(),
                        tile_version.contents_swizzled());
+          has_draw_quad = true;
           break;
         }
         case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
@@ -333,6 +343,7 @@
                        iter->content_rect(),
                        iter->contents_scale(),
                        pile_);
+          has_draw_quad = true;
           break;
         }
         case ManagedTileState::TileVersion::SOLID_COLOR_MODE: {
@@ -343,10 +354,13 @@
                        visible_geometry_rect,
                        tile_version.get_solid_color(),
                        false);
+          has_draw_quad = true;
           break;
         }
       }
-    } else {
+    }
+
+    if (!has_draw_quad) {
       if (draw_checkerboard_for_missing_tiles()) {
         CheckerboardDrawQuad* quad =
             render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
@@ -364,10 +378,12 @@
                      false);
       }
 
-      append_quads_data->num_missing_tiles++;
+      if (geometry_rect.Intersects(scaled_viewport_for_tile_priority)) {
+        append_quads_data->num_missing_tiles++;
+        ++missing_tile_count;
+      }
       append_quads_data->approximated_visible_content_area +=
           visible_geometry_rect.width() * visible_geometry_rect.height();
-      ++missing_tile_count;
       continue;
     }
 
@@ -472,6 +488,28 @@
   if (!tiling_needs_update)
     return;
 
+  gfx::Rect visible_rect_in_content_space(
+      GetViewportForTilePriorityInContentSpace());
+  visible_rect_in_content_space.Intersect(visible_content_rect());
+  gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
+      visible_rect_in_content_space, 1.f / contents_scale_x());
+  WhichTree tree =
+      layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
+  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
+    tilings_->tiling_at(i)->UpdateTilePriorities(tree,
+                                                 visible_layer_rect,
+                                                 ideal_contents_scale_,
+                                                 current_frame_time_in_seconds,
+                                                 occlusion_tracker,
+                                                 render_target(),
+                                                 draw_transform());
+  }
+
+  // Tile priorities were modified.
+  layer_tree_impl()->DidModifyTilePriorities();
+}
+
+gfx::Rect PictureLayerImpl::GetViewportForTilePriorityInContentSpace() const {
   // If visible_rect_for_tile_priority_ is empty or
   // viewport_rect_for_tile_priority_ is set to be different from the device
   // viewport, try to inverse project the viewport into layer space and use
@@ -492,22 +530,7 @@
     }
   }
 
-  gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
-      visible_rect_in_content_space, 1.f / contents_scale_x());
-  WhichTree tree =
-      layer_tree_impl()->IsActiveTree() ? ACTIVE_TREE : PENDING_TREE;
-  for (size_t i = 0; i < tilings_->num_tilings(); ++i) {
-    tilings_->tiling_at(i)->UpdateTilePriorities(tree,
-                                                 visible_layer_rect,
-                                                 ideal_contents_scale_,
-                                                 current_frame_time_in_seconds,
-                                                 occlusion_tracker,
-                                                 render_target(),
-                                                 draw_transform());
-  }
-
-  // Tile priorities were modified.
-  layer_tree_impl()->DidModifyTilePriorities();
+  return visible_rect_in_content_space;
 }
 
 void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) {
@@ -765,6 +788,12 @@
 
   gfx::Rect rect(visible_content_rect());
 
+  // Only mark tiles inside the viewport for tile priority as required for
+  // activation. This viewport is normally the same as the draw viewport but
+  // can be independently overridden by embedders like Android WebView with
+  // SetExternalDrawConstraints.
+  rect.Intersect(GetViewportForTilePriorityInContentSpace());
+
   float min_acceptable_scale =
       std::min(raster_contents_scale_, ideal_contents_scale_);
 
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 7623c4d..f70d3a2 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -172,6 +172,7 @@
       float contents_scale,
       const gfx::Rect& rect,
       const Region& missing_region) const;
+  gfx::Rect GetViewportForTilePriorityInContentSpace() const;
 
   void DoPostCommitInitializationIfNeeded() {
     if (needs_post_commit_initialization_)
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 5eae6a6..ec999e6 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -1450,6 +1450,97 @@
   EXPECT_GT(num_offscreen, 0);
 }
 
+TEST_F(PictureLayerImplTest, TileOutsideOfViewportForTilePriorityNotRequired) {
+  base::TimeTicks time_ticks;
+  time_ticks += base::TimeDelta::FromMilliseconds(1);
+  host_impl_.SetCurrentFrameTimeTicks(time_ticks);
+
+  gfx::Size tile_size(100, 100);
+  gfx::Size layer_bounds(400, 400);
+  gfx::Rect external_viewport_for_tile_priority(400, 200);
+  gfx::Rect visible_content_rect(200, 400);
+
+  scoped_refptr<FakePicturePileImpl> active_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  SetupTrees(pending_pile, active_pile);
+
+  active_layer_->set_fixed_tile_size(tile_size);
+  pending_layer_->set_fixed_tile_size(tile_size);
+  ASSERT_TRUE(pending_layer_->CanHaveTilings());
+  PictureLayerTiling* tiling = pending_layer_->AddTiling(1.f);
+
+  // Set external viewport for tile priority.
+  gfx::Rect viewport = gfx::Rect(layer_bounds);
+  gfx::Transform transform;
+  gfx::Transform transform_for_tile_priority;
+  bool resourceless_software_draw = false;
+  host_impl_.SetExternalDrawConstraints(transform,
+                                        viewport,
+                                        viewport,
+                                        external_viewport_for_tile_priority,
+                                        transform_for_tile_priority,
+                                        resourceless_software_draw);
+  host_impl_.pending_tree()->UpdateDrawProperties();
+
+  // Set visible content rect that is different from
+  // external_viewport_for_tile_priority.
+  pending_layer_->draw_properties().visible_content_rect = visible_content_rect;
+  time_ticks += base::TimeDelta::FromMilliseconds(200);
+  host_impl_.SetCurrentFrameTimeTicks(time_ticks);
+  pending_layer_->UpdateTiles(NULL);
+
+  pending_layer_->MarkVisibleResourcesAsRequired();
+
+  // Intersect the two rects. Any tile outside should not be required for
+  // activation.
+  gfx::Rect viewport_for_tile_priority =
+      pending_layer_->GetViewportForTilePriorityInContentSpace();
+  viewport_for_tile_priority.Intersect(pending_layer_->visible_content_rect());
+
+  int num_inside = 0;
+  int num_outside = 0;
+  for (PictureLayerTiling::CoverageIterator iter(
+           tiling, pending_layer_->contents_scale_x(), gfx::Rect(layer_bounds));
+       iter;
+       ++iter) {
+    if (!*iter)
+      continue;
+    Tile* tile = *iter;
+    if (viewport_for_tile_priority.Intersects(iter.geometry_rect())) {
+      num_inside++;
+      // Mark everything in viewport for tile priority as ready to draw.
+      ManagedTileState::TileVersion& tile_version =
+          tile->GetTileVersionForTesting(
+              tile->DetermineRasterModeForTree(PENDING_TREE));
+      tile_version.SetSolidColorForTesting(SK_ColorRED);
+    } else {
+      num_outside++;
+      EXPECT_FALSE(tile->required_for_activation());
+    }
+  }
+
+  EXPECT_GT(num_inside, 0);
+  EXPECT_GT(num_outside, 0);
+
+  // Activate and draw active layer.
+  host_impl_.ActivateSyncTree();
+  host_impl_.active_tree()->UpdateDrawProperties();
+  active_layer_->draw_properties().visible_content_rect = visible_content_rect;
+
+  MockOcclusionTracker<LayerImpl> occlusion_tracker;
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+  AppendQuadsData data;
+  active_layer_->WillDraw(DRAW_MODE_SOFTWARE, NULL);
+  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
+  active_layer_->DidDraw(NULL);
+
+  // All tiles in activation rect is ready to draw.
+  EXPECT_EQ(0u, data.num_missing_tiles);
+  EXPECT_EQ(0u, data.num_incomplete_tiles);
+}
+
 TEST_F(PictureLayerImplTest, HighResRequiredWhenUnsharedActiveAllReady) {
   gfx::Size layer_bounds(400, 400);
   gfx::Size tile_size(100, 100);
@@ -3101,6 +3192,66 @@
   EXPECT_NE(0u, pending_mask_content->num_tilings());
 }
 
+class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest {
+ public:
+  PictureLayerImplTestWithDelegatingRenderer() : PictureLayerImplTest() {}
+
+  virtual void InitializeRenderer() OVERRIDE {
+    host_impl_.InitializeRenderer(
+        FakeOutputSurface::CreateDelegating3d().PassAs<OutputSurface>());
+  }
+};
+
+TEST_F(PictureLayerImplTestWithDelegatingRenderer,
+       DelegatingRendererWithTileOOM) {
+  // This test is added for crbug.com/402321, where quad should be produced when
+  // raster on demand is not allowed and tile is OOM.
+  gfx::Size tile_size = host_impl_.settings().default_tile_size;
+  gfx::Size layer_bounds(1000, 1000);
+
+  // Create tiles.
+  scoped_refptr<FakePicturePileImpl> pending_pile =
+      FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
+  SetupPendingTree(pending_pile);
+  pending_layer_->SetBounds(layer_bounds);
+  host_impl_.SetViewportSize(layer_bounds);
+  ActivateTree();
+  host_impl_.active_tree()->UpdateDrawProperties();
+  std::vector<Tile*> tiles =
+      active_layer_->HighResTiling()->AllTilesForTesting();
+  host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(tiles);
+
+  // Force tiles after max_tiles to be OOM. TileManager uses
+  // GlobalStateThatImpactsTilesPriority from LayerTreeHostImpl, and we cannot
+  // directly set state to host_impl_, so we set policy that would change the
+  // state. We also need to update tree priority separately.
+  GlobalStateThatImpactsTilePriority state;
+  size_t max_tiles = 1;
+  size_t memory_limit = max_tiles * 4 * tile_size.width() * tile_size.height();
+  size_t resource_limit = max_tiles;
+  ManagedMemoryPolicy policy(memory_limit,
+                             gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
+                             resource_limit);
+  host_impl_.SetMemoryPolicy(policy);
+  host_impl_.SetTreePriority(SAME_PRIORITY_FOR_BOTH_TREES);
+  host_impl_.ManageTiles();
+
+  MockOcclusionTracker<LayerImpl> occlusion_tracker;
+  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
+  AppendQuadsData data;
+  active_layer_->WillDraw(DRAW_MODE_HARDWARE, NULL);
+  active_layer_->AppendQuads(render_pass.get(), occlusion_tracker, &data);
+  active_layer_->DidDraw(NULL);
+
+  // Even when OOM, quads should be produced, and should be different material
+  // from quads with resource.
+  EXPECT_LT(max_tiles, render_pass->quad_list.size());
+  EXPECT_EQ(DrawQuad::Material::TILED_CONTENT,
+            render_pass->quad_list.front()->material);
+  EXPECT_EQ(DrawQuad::Material::SOLID_COLOR,
+            render_pass->quad_list.back()->material);
+}
+
 class OcclusionTrackingSettings : public ImplSidePaintingSettings {
  public:
   OcclusionTrackingSettings() { use_occlusion_for_tile_prioritization = true; }
diff --git a/cc/resources/picture_layer_tiling.cc b/cc/resources/picture_layer_tiling.cc
index b335e50..947bb21 100644
--- a/cc/resources/picture_layer_tiling.cc
+++ b/cc/resources/picture_layer_tiling.cc
@@ -497,8 +497,7 @@
   eviction_tiles_cache_valid_ = false;
 
   TilePriority now_priority(resolution_, TilePriority::NOW, 0);
-  float content_to_screen_scale =
-      1.0f / (contents_scale_ * ideal_contents_scale);
+  float content_to_screen_scale = ideal_contents_scale / contents_scale_;
 
   // Assign now priority to all visible tiles.
   bool include_borders = true;
diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc
index 032ffec..a8caf48 100644
--- a/cc/resources/picture_layer_tiling_unittest.cc
+++ b/cc/resources/picture_layer_tiling_unittest.cc
@@ -622,13 +622,39 @@
       ACTIVE_TREE, viewport, 2.0f, 3.0, NULL, NULL, gfx::Transform());
 
   priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
-  EXPECT_FLOAT_EQ(34.f, priority.distance_to_visible);
+  EXPECT_FLOAT_EQ(136.f, priority.distance_to_visible);
 
   priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
-  EXPECT_FLOAT_EQ(14.f, priority.distance_to_visible);
+  EXPECT_FLOAT_EQ(56.f, priority.distance_to_visible);
 
   priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
   EXPECT_FLOAT_EQ(0.f, priority.distance_to_visible);
+
+  // Test additional scales.
+  tiling = TestablePictureLayerTiling::Create(0.2f, layer_bounds, &client);
+  tiling->UpdateTilePriorities(
+      ACTIVE_TREE, viewport, 1.0f, 4.0, NULL, NULL, gfx::Transform());
+
+  priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
+  EXPECT_FLOAT_EQ(110.f, priority.distance_to_visible);
+
+  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
+  EXPECT_FLOAT_EQ(70.f, priority.distance_to_visible);
+
+  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
+  EXPECT_FLOAT_EQ(60.f, priority.distance_to_visible);
+
+  tiling->UpdateTilePriorities(
+      ACTIVE_TREE, viewport, 0.5f, 5.0, NULL, NULL, gfx::Transform());
+
+  priority = tiling->TileAt(5, 1)->priority(ACTIVE_TREE);
+  EXPECT_FLOAT_EQ(55.f, priority.distance_to_visible);
+
+  priority = tiling->TileAt(2, 5)->priority(ACTIVE_TREE);
+  EXPECT_FLOAT_EQ(35.f, priority.distance_to_visible);
+
+  priority = tiling->TileAt(3, 4)->priority(ACTIVE_TREE);
+  EXPECT_FLOAT_EQ(30.f, priority.distance_to_visible);
 }
 
 TEST(PictureLayerTilingTest, ExpandRectEqual) {
diff --git a/cc/resources/picture_pile.cc b/cc/resources/picture_pile.cc
index 3037521..7ecd8b1 100644
--- a/cc/resources/picture_pile.cc
+++ b/cc/resources/picture_pile.cc
@@ -226,34 +226,143 @@
     gfx::Rect old_tiling_rect_over_tiles =
         tiling_.ExpandRectToTileBounds(gfx::Rect(old_tiling_size));
     if (min_toss_x < tiling_.num_tiles_x()) {
-      int unrecorded_left = std::max(tiling_.TilePositionX(min_toss_x),
-                                     interest_rect_over_tiles.right());
+      // The bounds which we want to invalidate are the tiles along the old
+      // edge of the pile. We'll call this bounding box the OLD EDGE RECT.
+      //
+      // In the picture below, the old edge rect would be the bounding box
+      // of tiles {h,i,j}. |min_toss_x| would be equal to the horizontal index
+      // of the same tiles.
+      //
+      //  old pile edge-v  new pile edge-v
+      // ---------------+ - - - - - - - -+
+      // mmppssvvyybbeeh|h               .
+      // mmppssvvyybbeeh|h               .
+      // nnqqttwwzzccffi|i               .
+      // nnqqttwwzzccffi|i               .
+      // oorruuxxaaddggj|j               .
+      // oorruuxxaaddggj|j               .
+      // ---------------+ - - - - - - - -+ <- old pile edge
+      //                                 .
+      //  - - - - - - - - - - - - - - - -+ <- new pile edge
+      //
+      // If you were to slide a vertical beam from the left edge of the
+      // old edge rect toward the right, it would either hit the right edge
+      // of the old edge rect, or the interest rect (expanded to the bounds
+      // of the tiles it touches). The same is true for a beam parallel to
+      // any of the four edges, sliding accross the old edge rect. We use
+      // the union of these four rectangles generated by these beams to
+      // determine which part of the old edge rect is outside of the expanded
+      // interest rect.
+      //
+      // Case 1: Intersect rect is outside the old edge rect. It can be
+      // either on the left or the right. The |left_rect| and |right_rect|,
+      // cover this case, one will be empty and one will cover the full
+      // old edge rect. In the picture below, |left_rect| would cover the
+      // old edge rect, and |right_rect| would be empty.
+      // +----------------------+ |^^^^^^^^^^^^^^^|
+      // |===>   OLD EDGE RECT  | |               |
+      // |===>                  | | INTEREST RECT |
+      // |===>                  | |               |
+      // |===>                  | |               |
+      // +----------------------+ |vvvvvvvvvvvvvvv|
+      //
+      // Case 2: Interest rect is inside the old edge rect. It will always
+      // fill the entire old edge rect horizontally since the old edge rect
+      // is a single tile wide, and the interest rect has been expanded to the
+      // bounds of the tiles it touches. In this case the |left_rect| and
+      // |right_rect| will be empty, but the case is handled by the |top_rect|
+      // and |bottom_rect|. In the picture below, neither the |top_rect| nor
+      // |bottom_rect| would empty, they would each cover the area of the old
+      // edge rect outside the expanded interest rect.
+      // +-----------------+
+      // |:::::::::::::::::|
+      // |:::::::::::::::::|
+      // |vvvvvvvvvvvvvvvvv|
+      // |                 |
+      // +-----------------+
+      // | INTEREST RECT   |
+      // |                 |
+      // +-----------------+
+      // |                 |
+      // | OLD EDGE RECT   |
+      // +-----------------+
+      //
+      // Lastly, we need to consider tiles inside the expanded interest rect.
+      // For those tiles, we want to invalidate exactly the newly exposed
+      // pixels. In the picture below the tiles in the old edge rect have been
+      // resized and the area covered by periods must be invalidated. The
+      // |exposed_rect| will cover exactly that area.
+      //           v-old pile edge
+      // +---------+-------+
+      // |         ........|
+      // |         ........|
+      // |  OLD EDGE.RECT..|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // |         ........|
+      // +---------+-------+
+
+      int left = tiling_.TilePositionX(min_toss_x);
+      int right = left + tiling_.TileSizeX(min_toss_x);
+      int top = old_tiling_rect_over_tiles.y();
+      int bottom = old_tiling_rect_over_tiles.bottom();
+
+      int left_until = std::min(interest_rect_over_tiles.x(), right);
+      int right_until = std::max(interest_rect_over_tiles.right(), left);
+      int top_until = std::min(interest_rect_over_tiles.y(), bottom);
+      int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
+
       int exposed_left = old_tiling_size.width();
-      int left = std::min(unrecorded_left, exposed_left);
-      int tile_right =
-          tiling_.TilePositionX(min_toss_x) + tiling_.TileSizeX(min_toss_x);
-      int exposed_right = tiling_size().width();
-      int right = std::min(tile_right, exposed_right);
-      gfx::Rect right_side(left,
-                           old_tiling_rect_over_tiles.y(),
-                           right - left,
-                           old_tiling_rect_over_tiles.height());
-      resize_invalidation.Union(right_side);
+      int exposed_left_until = right;
+      DCHECK_GE(exposed_left, left);
+
+      gfx::Rect left_rect(left, top, left_until - left, bottom - top);
+      gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
+      gfx::Rect top_rect(left, top, right - left, top_until - top);
+      gfx::Rect bottom_rect(
+          left, bottom_until, right - left, bottom - bottom_until);
+      gfx::Rect exposed_rect(
+          exposed_left, top, exposed_left_until - exposed_left, bottom - top);
+      resize_invalidation.Union(left_rect);
+      resize_invalidation.Union(right_rect);
+      resize_invalidation.Union(top_rect);
+      resize_invalidation.Union(bottom_rect);
+      resize_invalidation.Union(exposed_rect);
     }
     if (min_toss_y < tiling_.num_tiles_y()) {
-      int unrecorded_top = std::max(tiling_.TilePositionY(min_toss_y),
-                                    interest_rect_over_tiles.bottom());
+      // The same thing occurs here as in the case above, but the invalidation
+      // rect is the bounding box around the bottom row of tiles in the old
+      // pile. This would be tiles {o,r,u,x,a,d,g,j} in the above picture.
+
+      int top = tiling_.TilePositionY(min_toss_y);
+      int bottom = top + tiling_.TileSizeY(min_toss_y);
+      int left = old_tiling_rect_over_tiles.x();
+      int right = old_tiling_rect_over_tiles.right();
+
+      int top_until = std::min(interest_rect_over_tiles.y(), bottom);
+      int bottom_until = std::max(interest_rect_over_tiles.bottom(), top);
+      int left_until = std::min(interest_rect_over_tiles.x(), right);
+      int right_until = std::max(interest_rect_over_tiles.right(), left);
+
       int exposed_top = old_tiling_size.height();
-      int top = std::min(unrecorded_top, exposed_top);
-      int tile_bottom =
-          tiling_.TilePositionY(min_toss_y) + tiling_.TileSizeY(min_toss_y);
-      int exposed_bottom = tiling_size().height();
-      int bottom = std::min(tile_bottom, exposed_bottom);
-      gfx::Rect bottom_side(old_tiling_rect_over_tiles.x(),
-                            top,
-                            old_tiling_rect_over_tiles.width(),
-                            bottom - top);
-      resize_invalidation.Union(bottom_side);
+      int exposed_top_until = bottom;
+      DCHECK_GE(exposed_top, top);
+
+      gfx::Rect left_rect(left, top, left_until - left, bottom - top);
+      gfx::Rect right_rect(right_until, top, right - right_until, bottom - top);
+      gfx::Rect top_rect(left, top, right - left, top_until - top);
+      gfx::Rect bottom_rect(
+          left, bottom_until, right - left, bottom - bottom_until);
+      gfx::Rect exposed_rect(
+          left, exposed_top, right - left, exposed_top_until - exposed_top);
+      resize_invalidation.Union(left_rect);
+      resize_invalidation.Union(right_rect);
+      resize_invalidation.Union(top_rect);
+      resize_invalidation.Union(bottom_rect);
+      resize_invalidation.Union(exposed_rect);
     }
   }
 
diff --git a/cc/resources/picture_pile_unittest.cc b/cc/resources/picture_pile_unittest.cc
index 31e0a2a..c48b66c 100644
--- a/cc/resources/picture_pile_unittest.cc
+++ b/cc/resources/picture_pile_unittest.cc
@@ -36,9 +36,9 @@
     virtual ~TestPicturePile() {}
 };
 
-class PicturePileTest : public testing::Test {
+class PicturePileTestBase {
  public:
-  PicturePileTest()
+  PicturePileTestBase()
       : pile_(new TestPicturePile()),
         background_color_(SK_ColorBLUE),
         min_scale_(0.125),
@@ -91,6 +91,8 @@
   bool contents_opaque_;
 };
 
+class PicturePileTest : public PicturePileTestBase, public testing::Test {};
+
 TEST_F(PicturePileTest, SmallInvalidateInflated) {
   // Invalidate something inside a tile.
   Region invalidate_rect(gfx::Rect(50, 50, 1, 1));
@@ -384,14 +386,48 @@
   EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
 }
 
-TEST_F(PicturePileTest, ResizePileOutsideInterestRect) {
+enum Corner {
+  TOP_LEFT,
+  TOP_RIGHT,
+  BOTTOM_LEFT,
+  BOTTOM_RIGHT,
+};
+
+class PicturePileResizeCornerTest : public PicturePileTestBase,
+                                    public testing::TestWithParam<Corner> {
+ protected:
+  static gfx::Rect CornerSinglePixelRect(Corner corner, const gfx::Size& s) {
+    switch (corner) {
+      case TOP_LEFT:
+        return gfx::Rect(0, 0, 1, 1);
+      case TOP_RIGHT:
+        return gfx::Rect(s.width() - 1, 0, 1, 1);
+      case BOTTOM_LEFT:
+        return gfx::Rect(0, s.height() - 1, 1, 1);
+      case BOTTOM_RIGHT:
+        return gfx::Rect(s.width() - 1, s.height() - 1, 1, 1);
+    }
+    NOTREACHED();
+    return gfx::Rect();
+  }
+};
+
+TEST_P(PicturePileResizeCornerTest, ResizePileOutsideInterestRect) {
+  Corner corner = GetParam();
+
   // This size chosen to be larger than the interest rect size, which is
   // at least kPixelDistanceToRecord * 2 in each dimension.
   int tile_size = 100000;
-  gfx::Size base_tiling_size(5 * tile_size, 5 * tile_size);
-  gfx::Size grow_down_tiling_size(5 * tile_size, 7 * tile_size);
-  gfx::Size grow_right_tiling_size(7 * tile_size, 5 * tile_size);
-  gfx::Size grow_both_tiling_size(7 * tile_size, 7 * tile_size);
+  // The small number subtracted keeps the last tile in each axis larger than
+  // the interest rect also.
+  int offset = -100;
+  gfx::Size base_tiling_size(6 * tile_size + offset, 6 * tile_size + offset);
+  gfx::Size grow_down_tiling_size(6 * tile_size + offset,
+                                  8 * tile_size + offset);
+  gfx::Size grow_right_tiling_size(8 * tile_size + offset,
+                                   6 * tile_size + offset);
+  gfx::Size grow_both_tiling_size(8 * tile_size + offset,
+                                  8 * tile_size + offset);
 
   Region invalidation;
   Region expected_invalidation;
@@ -412,13 +448,15 @@
   }
 
   UpdateAndExpandInvalidation(
-      &invalidation, grow_down_tiling_size, gfx::Rect(1, 1));
+      &invalidation,
+      grow_down_tiling_size,
+      CornerSinglePixelRect(corner, grow_down_tiling_size));
 
   // We should have lost the recordings in the bottom row.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
   EXPECT_EQ(8, pile_->tiling().num_tiles_y());
-  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
-    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
+  for (int i = 0; i < 6; ++i) {
+    for (int j = 0; j < 6; ++j) {
       TestPicturePile::PictureMapKey key(i, j);
       TestPicturePile::PictureMap& map = pile_->picture_map();
       TestPicturePile::PictureMap::iterator it = map.find(key);
@@ -433,7 +471,9 @@
   invalidation.Clear();
 
   UpdateWholePile();
-  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
+  UpdateAndExpandInvalidation(&invalidation,
+                              base_tiling_size,
+                              CornerSinglePixelRect(corner, base_tiling_size));
 
   // We should have lost the recordings that are now outside the tiling only.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
@@ -454,13 +494,15 @@
 
   UpdateWholePile();
   UpdateAndExpandInvalidation(
-      &invalidation, grow_right_tiling_size, gfx::Rect(1, 1));
+      &invalidation,
+      grow_right_tiling_size,
+      CornerSinglePixelRect(corner, grow_right_tiling_size));
 
   // We should have lost the recordings in the right column.
   EXPECT_EQ(8, pile_->tiling().num_tiles_x());
   EXPECT_EQ(6, pile_->tiling().num_tiles_y());
-  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
-    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
+  for (int i = 0; i < 6; ++i) {
+    for (int j = 0; j < 6; ++j) {
       TestPicturePile::PictureMapKey key(i, j);
       TestPicturePile::PictureMap& map = pile_->picture_map();
       TestPicturePile::PictureMap::iterator it = map.find(key);
@@ -475,7 +517,9 @@
   invalidation.Clear();
 
   UpdateWholePile();
-  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
+  UpdateAndExpandInvalidation(&invalidation,
+                              base_tiling_size,
+                              CornerSinglePixelRect(corner, base_tiling_size));
 
   // We should have lost the recordings that are now outside the tiling only.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
@@ -496,13 +540,15 @@
 
   UpdateWholePile();
   UpdateAndExpandInvalidation(
-      &invalidation, grow_both_tiling_size, gfx::Rect(1, 1));
+      &invalidation,
+      grow_both_tiling_size,
+      CornerSinglePixelRect(corner, grow_both_tiling_size));
 
   // We should have lost the recordings in the right column and bottom row.
   EXPECT_EQ(8, pile_->tiling().num_tiles_x());
   EXPECT_EQ(8, pile_->tiling().num_tiles_y());
-  for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
-    for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
+  for (int i = 0; i < 6; ++i) {
+    for (int j = 0; j < 6; ++j) {
       TestPicturePile::PictureMapKey key(i, j);
       TestPicturePile::PictureMap& map = pile_->picture_map();
       TestPicturePile::PictureMap::iterator it = map.find(key);
@@ -539,14 +585,22 @@
   invalidation.Clear();
 }
 
-TEST_F(PicturePileTest, SmallResizePileOutsideInterestRect) {
+TEST_P(PicturePileResizeCornerTest, SmallResizePileOutsideInterestRect) {
+  Corner corner = GetParam();
+
   // This size chosen to be larger than the interest rect size, which is
   // at least kPixelDistanceToRecord * 2 in each dimension.
   int tile_size = 100000;
-  gfx::Size base_tiling_size(5 * tile_size, 5 * tile_size);
-  gfx::Size grow_down_tiling_size(5 * tile_size, 5 * tile_size + 5);
-  gfx::Size grow_right_tiling_size(5 * tile_size + 5, 5 * tile_size);
-  gfx::Size grow_both_tiling_size(5 * tile_size + 5, 5 * tile_size + 5);
+  // The small number subtracted keeps the last tile in each axis larger than
+  // the interest rect also.
+  int offset = -100;
+  gfx::Size base_tiling_size(6 * tile_size + offset, 6 * tile_size + offset);
+  gfx::Size grow_down_tiling_size(6 * tile_size + offset,
+                                  6 * tile_size + offset + 5);
+  gfx::Size grow_right_tiling_size(6 * tile_size + offset + 5,
+                                   6 * tile_size + offset);
+  gfx::Size grow_both_tiling_size(6 * tile_size + offset + 5,
+                                  6 * tile_size + offset + 5);
 
   Region invalidation;
   Region expected_invalidation;
@@ -567,9 +621,12 @@
   }
 
   UpdateAndExpandInvalidation(
-      &invalidation, grow_down_tiling_size, gfx::Rect(1, 1));
+      &invalidation,
+      grow_down_tiling_size,
+      CornerSinglePixelRect(corner, grow_down_tiling_size));
 
-  // We should have lost the recordings in the bottom row.
+  // We should have lost the recordings in the bottom row that do not intersect
+  // the interest rect.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
   EXPECT_EQ(6, pile_->tiling().num_tiles_y());
   for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
@@ -577,18 +634,53 @@
       TestPicturePile::PictureMapKey key(i, j);
       TestPicturePile::PictureMap& map = pile_->picture_map();
       TestPicturePile::PictureMap::iterator it = map.find(key);
-      EXPECT_EQ(j < 5, it != map.end() && it->second.GetPicture());
+      bool expect_tile;
+      switch (corner) {
+        case TOP_LEFT:
+        case TOP_RIGHT:
+          expect_tile = j < 5;
+          break;
+        case BOTTOM_LEFT:
+          // The interest rect in the bottom left tile means we'll record it.
+          expect_tile = j < 5 || (j == 5 && i == 0);
+          break;
+        case BOTTOM_RIGHT:
+          // The interest rect in the bottom right tile means we'll record it.
+          expect_tile = j < 5 || (j == 5 && i == 5);
+          break;
+      }
+      EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
     }
   }
 
-  // We invalidated the bottom row.
-  expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5),
-                                          pile_->tiling().TileBounds(5, 5));
+  // We invalidated the bottom row outside the new interest rect. The tile that
+  // insects the interest rect in invalidated only on its new pixels.
+  switch (corner) {
+    case TOP_LEFT:
+    case TOP_RIGHT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5),
+                                              pile_->tiling().TileBounds(5, 5));
+      break;
+    case BOTTOM_LEFT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(1, 5),
+                                              pile_->tiling().TileBounds(5, 5));
+      expected_invalidation.Union(SubtractRects(
+          pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
+      break;
+    case BOTTOM_RIGHT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(0, 5),
+                                              pile_->tiling().TileBounds(4, 5));
+      expected_invalidation.Union(SubtractRects(
+          pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
+      break;
+  }
   EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
   invalidation.Clear();
 
   UpdateWholePile();
-  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
+  UpdateAndExpandInvalidation(&invalidation,
+                              base_tiling_size,
+                              CornerSinglePixelRect(corner, base_tiling_size));
 
   // We should have lost nothing.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
@@ -609,7 +701,9 @@
 
   UpdateWholePile();
   UpdateAndExpandInvalidation(
-      &invalidation, grow_right_tiling_size, gfx::Rect(1, 1));
+      &invalidation,
+      grow_right_tiling_size,
+      CornerSinglePixelRect(corner, grow_right_tiling_size));
 
   // We should have lost the recordings in the right column.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
@@ -619,18 +713,53 @@
       TestPicturePile::PictureMapKey key(i, j);
       TestPicturePile::PictureMap& map = pile_->picture_map();
       TestPicturePile::PictureMap::iterator it = map.find(key);
-      EXPECT_EQ(i < 5, it != map.end() && it->second.GetPicture());
+      bool expect_tile;
+      switch (corner) {
+        case TOP_LEFT:
+        case BOTTOM_LEFT:
+          expect_tile = i < 5;
+          break;
+        case TOP_RIGHT:
+          // The interest rect in the top right tile means we'll record it.
+          expect_tile = i < 5 || (j == 0 && i == 5);
+          break;
+        case BOTTOM_RIGHT:
+          // The interest rect in the bottom right tile means we'll record it.
+          expect_tile = i < 5 || (j == 5 && i == 5);
+          break;
+      }
+      EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture());
     }
   }
 
-  // We invalidated the right column.
-  expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
-                                          pile_->tiling().TileBounds(5, 5));
+  // We invalidated the right column outside the new interest rect. The tile
+  // that insects the interest rect in invalidated only on its new pixels.
+  switch (corner) {
+    case TOP_LEFT:
+    case BOTTOM_LEFT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
+                                              pile_->tiling().TileBounds(5, 5));
+      break;
+    case TOP_RIGHT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 1),
+                                              pile_->tiling().TileBounds(5, 5));
+      expected_invalidation.Union(SubtractRects(
+          pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
+      break;
+    case BOTTOM_RIGHT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
+                                              pile_->tiling().TileBounds(5, 4));
+      expected_invalidation.Union(SubtractRects(
+          pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
+      break;
+  }
   EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
   invalidation.Clear();
 
   UpdateWholePile();
-  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
+  UpdateAndExpandInvalidation(&invalidation,
+                              base_tiling_size,
+                              CornerSinglePixelRect(corner, base_tiling_size));
 
   // We should have lost nothing.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
@@ -651,9 +780,12 @@
 
   UpdateWholePile();
   UpdateAndExpandInvalidation(
-      &invalidation, grow_both_tiling_size, gfx::Rect(1, 1));
+      &invalidation,
+      grow_both_tiling_size,
+      CornerSinglePixelRect(corner, grow_both_tiling_size));
 
-  // We should have lost the recordings in the right column and bottom row.
+  // We should have lost the recordings in the right column and bottom row. The
+  // tile that insects the interest rect in invalidated only on its new pixels.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
   EXPECT_EQ(6, pile_->tiling().num_tiles_y());
   for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
@@ -661,20 +793,71 @@
       TestPicturePile::PictureMapKey key(i, j);
       TestPicturePile::PictureMap& map = pile_->picture_map();
       TestPicturePile::PictureMap::iterator it = map.find(key);
-      EXPECT_EQ(i < 5 && j < 5, it != map.end() && it->second.GetPicture());
+      bool expect_tile;
+      switch (corner) {
+        case TOP_LEFT:
+          expect_tile = i < 5 && j < 5;
+          break;
+        case TOP_RIGHT:
+          // The interest rect in the top right tile means we'll record it.
+          expect_tile = (i < 5 && j < 5) || (j == 0 && i == 5);
+          break;
+        case BOTTOM_LEFT:
+          // The interest rect in the bottom left tile means we'll record it.
+          expect_tile = (i < 5 && j < 5) || (j == 5 && i == 0);
+          break;
+        case BOTTOM_RIGHT:
+          // The interest rect in the bottom right tile means we'll record it.
+          expect_tile = (i < 5 && j < 5) || (j == 5 && i == 5);
+          break;
+      }
+      EXPECT_EQ(expect_tile, it != map.end() && it->second.GetPicture())
+          << i << "," << j;
     }
   }
 
-  // We invalidated the right column and the bottom row.
-  expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
-                                          pile_->tiling().TileBounds(5, 5));
-  expected_invalidation.Union(gfx::UnionRects(
-      pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5)));
+  // We invalidated the right column and the bottom row outside the new interest
+  // rect. The tile that insects the interest rect in invalidated only on its
+  // new pixels.
+  switch (corner) {
+    case TOP_LEFT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
+                                              pile_->tiling().TileBounds(5, 5));
+      expected_invalidation.Union(gfx::UnionRects(
+          pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5)));
+      break;
+    case TOP_RIGHT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 1),
+                                              pile_->tiling().TileBounds(5, 5));
+      expected_invalidation.Union(gfx::UnionRects(
+          pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(5, 5)));
+      expected_invalidation.Union(SubtractRects(
+          pile_->tiling().TileBounds(5, 0), gfx::Rect(base_tiling_size)));
+      break;
+    case BOTTOM_LEFT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
+                                              pile_->tiling().TileBounds(5, 5));
+      expected_invalidation.Union(gfx::UnionRects(
+          pile_->tiling().TileBounds(1, 5), pile_->tiling().TileBounds(5, 5)));
+      expected_invalidation.Union(SubtractRects(
+          pile_->tiling().TileBounds(0, 5), gfx::Rect(base_tiling_size)));
+      break;
+    case BOTTOM_RIGHT:
+      expected_invalidation = gfx::UnionRects(pile_->tiling().TileBounds(5, 0),
+                                              pile_->tiling().TileBounds(5, 4));
+      expected_invalidation.Union(gfx::UnionRects(
+          pile_->tiling().TileBounds(0, 5), pile_->tiling().TileBounds(4, 5)));
+      expected_invalidation.Union(SubtractRegions(
+          pile_->tiling().TileBounds(5, 5), gfx::Rect(base_tiling_size)));
+      break;
+  }
   EXPECT_EQ(expected_invalidation.ToString(), invalidation.ToString());
   invalidation.Clear();
 
   UpdateWholePile();
-  UpdateAndExpandInvalidation(&invalidation, base_tiling_size, gfx::Rect(1, 1));
+  UpdateAndExpandInvalidation(&invalidation,
+                              base_tiling_size,
+                              CornerSinglePixelRect(corner, base_tiling_size));
 
   // We should have lost nothing.
   EXPECT_EQ(6, pile_->tiling().num_tiles_x());
@@ -694,6 +877,11 @@
   invalidation.Clear();
 }
 
+INSTANTIATE_TEST_CASE_P(
+    PicturePileResizeCornerTests,
+    PicturePileResizeCornerTest,
+    ::testing::Values(TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT));
+
 TEST_F(PicturePileTest, ResizePileInsideInterestRect) {
   // This size chosen to be small enough that all the rects below fit inside the
   // the interest rect, so they are smaller than kPixelDistanceToRecord in each
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc
index d755473..67ae593 100644
--- a/cc/resources/pixel_buffer_raster_worker_pool.cc
+++ b/cc/resources/pixel_buffer_raster_worker_pool.cc
@@ -515,10 +515,13 @@
       continue;
     }
 
-    // All raster tasks need to be throttled by bytes of pending uploads.
+    // All raster tasks need to be throttled by bytes of pending uploads,
+    // but if it's the only task allow it to complete no matter what its size,
+    // to prevent starvation of the task queue.
     size_t new_bytes_pending_upload = bytes_pending_upload;
     new_bytes_pending_upload += task->resource()->bytes();
-    if (new_bytes_pending_upload > max_bytes_pending_upload_) {
+    if (new_bytes_pending_upload > max_bytes_pending_upload_ &&
+        bytes_pending_upload) {
       did_throttle_raster_tasks = true;
       if (item.required_for_activation)
         did_throttle_raster_tasks_required_for_activation = true;
diff --git a/cc/resources/prioritized_tile_set.cc b/cc/resources/prioritized_tile_set.cc
index 82c7f16..d0104cb 100644
--- a/cc/resources/prioritized_tile_set.cc
+++ b/cc/resources/prioritized_tile_set.cc
@@ -40,13 +40,20 @@
 
 namespace {
 
+bool TilePriorityTieBreaker(const Tile* tile_i, const Tile* tile_j) {
+  // When two tiles has same priority use Id as tie breaker.
+  return tile_i->id() < tile_j->id();
+}
+
 typedef std::vector<Tile*> TileVector;
 
 void SortBinTiles(ManagedTileBin bin, TileVector* tiles) {
   switch (bin) {
-    case NOW_AND_READY_TO_DRAW_BIN:
     case NEVER_BIN:
       break;
+    case NOW_AND_READY_TO_DRAW_BIN:
+      std::sort(tiles->begin(), tiles->end(), TilePriorityTieBreaker);
+      break;
     case NOW_BIN:
     case SOON_BIN:
     case EVENTUALLY_AND_ACTIVE_BIN:
diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc
index 3b43c09..2179161 100644
--- a/cc/resources/raster_worker_pool_unittest.cc
+++ b/cc/resources/raster_worker_pool_unittest.cc
@@ -27,6 +27,11 @@
 namespace cc {
 namespace {
 
+const size_t kMaxTransferBufferUsageBytes = 10000U;
+// A resource of this dimension^2 * 4 must be greater than the above transfer
+// buffer constant.
+const size_t kLargeResourceDimension = 1000U;
+
 enum RasterWorkerPoolType {
   RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
   RASTER_WORKER_POOL_TYPE_IMAGE,
@@ -126,7 +131,7 @@
             RasterWorkerPool::GetTaskGraphRunner(),
             context_provider_.get(),
             resource_provider_.get(),
-            std::numeric_limits<size_t>::max());
+            kMaxTransferBufferUsageBytes);
         break;
       case RASTER_WORKER_POOL_TYPE_IMAGE:
         raster_worker_pool_ = ImageRasterWorkerPool::Create(
@@ -203,9 +208,7 @@
     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
   }
 
-  void AppendTask(unsigned id) {
-    const gfx::Size size(1, 1);
-
+  void AppendTask(unsigned id, const gfx::Size& size) {
     scoped_ptr<ScopedResource> resource(
         ScopedResource::Create(resource_provider_.get()));
     resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
@@ -221,6 +224,8 @@
         &empty));
   }
 
+  void AppendTask(unsigned id) { AppendTask(id, gfx::Size(1, 1)); }
+
   void AppendBlockingTask(unsigned id, base::Lock* lock) {
     const gfx::Size size(1, 1);
 
@@ -324,6 +329,27 @@
   RunMessageLoopUntilAllTasksHaveCompleted();
 }
 
+TEST_P(RasterWorkerPoolTest, LargeResources) {
+  gfx::Size size(kLargeResourceDimension, kLargeResourceDimension);
+
+  {
+    // Verify a resource of this size is larger than the transfer buffer.
+    scoped_ptr<ScopedResource> resource(
+        ScopedResource::Create(resource_provider_.get()));
+    resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
+    EXPECT_GE(resource->bytes(), kMaxTransferBufferUsageBytes);
+  }
+
+  AppendTask(0u, size);
+  AppendTask(1u, size);
+  AppendTask(2u, size);
+  ScheduleTasks();
+
+  // This will time out if a resource that is larger than the throttle limit
+  // never gets scheduled.
+  RunMessageLoopUntilAllTasksHaveCompleted();
+}
+
 INSTANTIATE_TEST_CASE_P(RasterWorkerPoolTests,
                         RasterWorkerPoolTest,
                         ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 30d5849..d88bdd2 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -111,25 +111,16 @@
   return kSkia8888_GrPixelConfig;
 }
 
-class IdentityAllocator : public SkBitmap::Allocator {
- public:
-  explicit IdentityAllocator(void* buffer) : buffer_(buffer) {}
-  virtual bool allocPixelRef(SkBitmap* dst, SkColorTable*) OVERRIDE {
-    dst->setPixels(buffer_);
-    return true;
-  }
-
- private:
-  void* buffer_;
-};
-
-void CopyBitmap(const SkBitmap& src, uint8_t* dst, SkColorType dst_colorType) {
-  SkBitmap dst_bitmap;
-  IdentityAllocator allocator(dst);
-  src.copyTo(&dst_bitmap, dst_colorType, &allocator);
+void CopyBitmap(const SkBitmap& src, uint8_t* dst, SkColorType dst_color_type) {
+  SkImageInfo dst_info = src.info();
+  dst_info.fColorType = dst_color_type;
   // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
-  // bitmap data. This check will be removed once crbug.com/293728 is fixed.
-  CHECK_EQ(0u, dst_bitmap.rowBytes() % 4);
+  // bitmap data. There will be no need to call SkAlign4 once crbug.com/293728
+  // is fixed.
+  const size_t dst_row_bytes = SkAlign4(dst_info.minRowBytes());
+  CHECK_EQ(0u, dst_row_bytes % 4);
+  bool success = src.readPixels(dst_info, dst, dst_row_bytes, 0, 0);
+  CHECK_EQ(true, success);
 }
 
 class ScopedSetActiveTexture {
diff --git a/cc/resources/tile.h b/cc/resources/tile.h
index 6588ac5..5e1ce5a 100644
--- a/cc/resources/tile.h
+++ b/cc/resources/tile.h
@@ -131,6 +131,7 @@
 
   void set_picture_pile(scoped_refptr<PicturePileImpl> pile) {
     DCHECK(pile->CanRaster(contents_scale_, content_rect_))
+        << "Recording rect: "
         << gfx::ScaleToEnclosingRect(content_rect_, 1.f / contents_scale_)
                .ToString();
     picture_pile_ = pile;
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index fa5c650..eec5629 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -123,7 +123,8 @@
       ManagedTileState::TileVersion& tile_version =
           mts.tile_versions[HIGH_QUALITY_RASTER_MODE];
 
-      tile_version.resource_ = resource_pool_->AcquireResource(gfx::Size(1, 1));
+      tile_version.resource_ =
+          resource_pool_->AcquireResource(tiles[i]->size());
 
       bytes_releasable_ += BytesConsumedIfAllocated(tiles[i]);
       ++resources_releasable_;
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index d113e8b..bf72b45 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -249,11 +249,7 @@
     {
       ResourceProvider::ScopedWriteLockSoftware lock(
           resource_provider_, plane_resources[0].resource_id);
-      video_renderer_->Paint(video_frame.get(),
-                             lock.sk_canvas(),
-                             video_frame->visible_rect(),
-                             0xff,
-                             media::VIDEO_ROTATION_0);
+      video_renderer_->Copy(video_frame.get(), lock.sk_canvas());
     }
 
     RecycleResourceData recycle_data = {
diff --git a/cc/test/fake_picture_layer_impl.h b/cc/test/fake_picture_layer_impl.h
index 86d83ba..4b68d7f 100644
--- a/cc/test/fake_picture_layer_impl.h
+++ b/cc/test/fake_picture_layer_impl.h
@@ -58,6 +58,7 @@
   using PictureLayerImpl::MarkVisibleResourcesAsRequired;
   using PictureLayerImpl::DoPostCommitInitializationIfNeeded;
   using PictureLayerImpl::MinimumContentsScale;
+  using PictureLayerImpl::GetViewportForTilePriorityInContentSpace;
   using PictureLayerImpl::SanityCheckTilingState;
 
   using PictureLayerImpl::UpdateIdealScales;
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc
index a466d87..b4d580f 100644
--- a/cc/test/test_in_process_context_provider.cc
+++ b/cc/test/test_in_process_context_provider.cc
@@ -36,16 +36,18 @@
   attribs.bind_generates_resource = false;
   gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
 
-  scoped_ptr<gpu::GLInProcessContext> context = make_scoped_ptr(
-      gpu::GLInProcessContext::Create(NULL,
-                                      NULL,
-                                      is_offscreen,
-                                      gfx::kNullAcceleratedWidget,
-                                      gfx::Size(1, 1),
-                                      NULL,
-                                      share_resources,
-                                      attribs,
-                                      gpu_preference));
+  scoped_ptr<gpu::GLInProcessContext> context =
+      make_scoped_ptr(gpu::GLInProcessContext::Create(
+          NULL,
+          NULL,
+          is_offscreen,
+          gfx::kNullAcceleratedWidget,
+          gfx::Size(1, 1),
+          NULL,
+          share_resources,
+          attribs,
+          gpu_preference,
+          gpu::GLInProcessContextSharedMemoryLimits()));
 
   DCHECK(context);
   return context.Pass();
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 167b65a..f01d0f9 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -3040,6 +3040,21 @@
                  wheel_scroll_delta);
 }
 
+TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
+  int width = 332;
+  int height = 20;
+  int scale = 3;
+  SetupScrollAndContentsLayers(gfx::Size(width, height));
+  host_impl_->SetViewportSize(gfx::Size(width * scale - 1, height * scale));
+  host_impl_->SetDeviceScaleFactor(scale);
+  host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+
+  LayerImpl* inner_viewport_scroll_layer =
+      host_impl_->active_tree()->InnerViewportScrollLayer();
+  EXPECT_EQ(gfx::Vector2d(0, 0),
+            inner_viewport_scroll_layer->MaxScrollOffset());
+}
+
 class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
  public:
   TestScrollOffsetDelegate()
diff --git a/chrome/VERSION b/chrome/VERSION
index c61ab1f..4173e24 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=38
 MINOR=0
 BUILD=2125
-PATCH=23
+PATCH=57
diff --git a/chrome/android/java/res/anim/menu_enter.xml b/chrome/android/java/res/anim/menu_enter.xml
index 63194a9..e6c4936 100644
--- a/chrome/android/java/res/anim/menu_enter.xml
+++ b/chrome/android/java/res/anim/menu_enter.xml
@@ -16,4 +16,8 @@
     <alpha android:interpolator="@android:anim/linear_interpolator"
         android:fromAlpha="0" android:toAlpha="1"
         android:duration="200" />
+    <translate android:interpolator="@interpolator/transform_curve_interpolator"
+        android:fromYDelta="@dimen/menu_negative_software_vertical_offset"
+        android:toYDelta="0"
+        android:duration="200" />
 </set>
\ No newline at end of file
diff --git a/chrome/android/java/res/values-sw600dp/dimens.xml b/chrome/android/java/res/values-sw600dp/dimens.xml
index d8fed33..ba5395e 100644
--- a/chrome/android/java/res/values-sw600dp/dimens.xml
+++ b/chrome/android/java/res/values-sw600dp/dimens.xml
@@ -7,5 +7,5 @@
 <resources>
     <!-- Menu Dimensions -->
     <!-- Necessary to align the menu icon with the actual button. -->
-    <dimen name="menu_software_vertical_offset">-6dp</dimen>
+    <dimen name="menu_negative_software_vertical_offset">6dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 72172f2..fa87b13 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -17,7 +17,7 @@
 
     <!-- Custom Menu dimensions -->
     <dimen name="menu_width">258dp</dimen>
-    <dimen name="menu_software_vertical_offset">0dp</dimen>
+    <dimen name="menu_negative_software_vertical_offset">0dp</dimen>
     <!-- The amount to fade the edges of the menu to indicate more content is available
          via scrolling. -->
     <dimen name="menu_vertical_fade_distance">15dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/EmptyTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/EmptyTabObserver.java
index 2ec6b9b..56c8a44 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/EmptyTabObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/EmptyTabObserver.java
@@ -39,6 +39,9 @@
     public void onContextMenuShown(Tab tab, ContextMenu menu) { }
 
     @Override
+    public void onWebContentsInstantSupportDisabled() { }
+
+    @Override
     public void onLoadStarted(Tab tabBase) { }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
index c76ebc3..3c4a5b6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/Tab.java
@@ -830,6 +830,11 @@
         }
 
         for (TabObserver observer : mObservers) observer.onContentChanged(this);
+
+        // For browser tabs, we want to set accessibility focus to the page
+        // when it loads. This is not the default behavior for embedded
+        // web views.
+        mContentViewCore.setShouldSetAccessibilityFocusOnPageLoad(true);
     }
 
     /**
@@ -998,6 +1003,15 @@
     }
 
     /**
+     * A helper method to allow subclasses to handle the Instant support
+     * disabled event.
+     */
+    @CalledByNative
+    private void onWebContentsInstantSupportDisabled() {
+      for (TabObserver observer : mObservers) observer.onWebContentsInstantSupportDisabled();
+    }
+
+    /**
      * A helper method to allow subclasses to build their own menu populator.
      * @return An instance of a {@link ContextMenuPopulator}.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/TabObserver.java
index 42f0eb6..e801bc1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/TabObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/TabObserver.java
@@ -78,6 +78,11 @@
      */
     void onContextMenuShown(Tab tab, ContextMenu menu);
 
+    /**
+     * Called when the WebContents Instant support is disabled.
+     */
+    void onWebContentsInstantSupportDisabled();
+
     // WebContentsDelegateAndroid methods ---------------------------------------------------------
 
     /**
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 af48e84..3f3ac68 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
@@ -9,6 +9,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -46,7 +47,7 @@
     private final int mItemRowHeight;
     private final int mItemDividerHeight;
     private final int mVerticalFadeDistance;
-    private final int mAdditionalVerticalOffset;
+    private final int mNegativeSoftwareVerticalOffset;
     private ListPopupWindow mPopup;
     private AppMenuAdapter mAdapter;
     private AppMenuHandler mHandler;
@@ -73,8 +74,8 @@
         mItemDividerHeight = itemDividerHeight;
         assert mItemDividerHeight >= 0;
 
-        mAdditionalVerticalOffset =
-                res.getDimensionPixelSize(R.dimen.menu_software_vertical_offset);
+        mNegativeSoftwareVerticalOffset =
+                res.getDimensionPixelSize(R.dimen.menu_negative_software_vertical_offset);
         mVerticalFadeDistance = res.getDimensionPixelSize(R.dimen.menu_vertical_fade_distance);
     }
 
@@ -106,6 +107,11 @@
             }
         });
 
+        // Some OEMs don't actually let us change the background... but they still return the
+        // padding of the new background, which breaks the menu height.  If we still have a
+        // drawable here even though our style says @null we should use this padding instead...
+        Drawable originalBgDrawable = mPopup.getBackground();
+
         // Need to explicitly set the background here.  Relying on it being set in the style caused
         // an incorrectly drawn background.
         if (isByHardwareButton) {
@@ -140,6 +146,14 @@
             }
         }
 
+        Rect sizingPadding = new Rect(bgPadding);
+        if (isByHardwareButton && originalBgDrawable != null) {
+            Rect originalPadding = new Rect();
+            originalBgDrawable.getPadding(originalPadding);
+            sizingPadding.top = originalPadding.top;
+            sizingPadding.bottom = originalPadding.bottom;
+        }
+
         boolean showMenuButton = !mIsByHardwareButton;
         if (!SHOW_SW_MENU_BUTTON) showMenuButton = false;
         // A List adapter for visible items in the Menu. The first row is added as a header to the
@@ -148,8 +162,8 @@
                 this, menuItems, LayoutInflater.from(context), showMenuButton);
         mPopup.setAdapter(mAdapter);
 
-        setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight);
-        setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame);
+        setMenuHeight(menuItems.size(), visibleDisplayFrame, screenHeight, sizingPadding);
+        setPopupOffset(mPopup, mCurrentScreenRotation, visibleDisplayFrame, sizingPadding);
         mPopup.setOnItemClickListener(this);
         mPopup.show();
         mPopup.getListView().setItemsCanFocus(true);
@@ -175,9 +189,8 @@
         }
     }
 
-    private void setPopupOffset(ListPopupWindow popup, int screenRotation, Rect appRect) {
-        Rect paddingRect = new Rect();
-        popup.getBackground().getPadding(paddingRect);
+    private void setPopupOffset(
+            ListPopupWindow popup, int screenRotation, Rect appRect, Rect padding) {
         int[] anchorLocation = new int[2];
         popup.getAnchorView().getLocationInWindow(anchorLocation);
         int anchorHeight = popup.getAnchorView().getHeight();
@@ -201,13 +214,13 @@
                     break;
             }
             popup.setHorizontalOffset(horizontalOffset);
-            // The menu is displayed above the anchored view, so shift the menu up by the top
+            // The menu is displayed above the anchored view, so shift the menu up by the bottom
             // padding of the background.
-            popup.setVerticalOffset(-paddingRect.bottom);
+            popup.setVerticalOffset(-padding.bottom);
         } else {
             // The menu is displayed over and below the anchored view, so shift the menu up by the
             // height of the anchor view.
-            popup.setVerticalOffset(mAdditionalVerticalOffset - anchorHeight);
+            popup.setVerticalOffset(-mNegativeSoftwareVerticalOffset - anchorHeight);
         }
     }
 
@@ -274,7 +287,8 @@
         return mPopup;
     }
 
-    private void setMenuHeight(int numMenuItems, Rect appDimensions, int screenHeight) {
+    private void setMenuHeight(
+            int numMenuItems, Rect appDimensions, int screenHeight, Rect padding) {
         assert mPopup.getAnchorView() != null;
         View anchorView = mPopup.getAnchorView();
         int[] anchorViewLocation = new int[2];
@@ -289,9 +303,8 @@
         int availableScreenSpace = Math.max(anchorViewLocation[1],
                 appDimensions.height() - anchorViewLocation[1] - anchorViewImpactHeight);
 
-        Rect padding = new Rect();
-        mPopup.getBackground().getPadding(padding);
-        availableScreenSpace -= mIsByHardwareButton ? padding.top : padding.bottom;
+        availableScreenSpace -= padding.bottom;
+        if (mIsByHardwareButton) availableScreenSpace -= padding.top;
 
         int numCanFit = availableScreenSpace / (mItemRowHeight + mItemDividerHeight);
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
index 30dd6c2..6f3bf0c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -57,11 +57,11 @@
      * @param screenshot Screenshot of the page to be shared.
      */
     public static void share(boolean shareDirectly, Activity activity, String title, String url,
-            Bitmap screenshot) {
+            Bitmap screenshot, int extraIntentFlags) {
         if (shareDirectly) {
-            shareWithLastUsed(activity, title, url, screenshot);
+            shareWithLastUsed(activity, title, url, screenshot, extraIntentFlags);
         } else {
-            showShareDialog(activity, title, url, screenshot);
+            showShareDialog(activity, title, url, screenshot, extraIntentFlags);
         }
     }
 
@@ -72,10 +72,11 @@
      * @param title Title of the page to be shared.
      * @param url URL of the page to be shared.
      * @param screenshot Screenshot of the page to be shared.
+     * @param extraIntentFlags Additional flags that should be added to the share intent.
      */
     private static void showShareDialog(final Activity activity, final String title,
-            final String url, final Bitmap screenshot) {
-        Intent intent = getShareIntent(title, url, screenshot);
+            final String url, final Bitmap screenshot, final int extraIntentFlags) {
+        Intent intent = getShareIntent(title, url, screenshot, extraIntentFlags);
         PackageManager manager = activity.getPackageManager();
         List<ResolveInfo> resolveInfoList = manager.queryIntentActivities(intent, 0);
         assert resolveInfoList.size() > 0;
@@ -98,7 +99,8 @@
                 ComponentName component =
                         new ComponentName(ai.applicationInfo.packageName, ai.name);
                 setLastShareComponentName(activity, component);
-                Intent intent = getDirectShareIntentForComponent(title, url, screenshot, component);
+                Intent intent = getDirectShareIntentForComponent(title, url, screenshot, component,
+                        extraIntentFlags);
                 activity.startActivity(intent);
                 dialog.dismiss();
             }
@@ -112,12 +114,14 @@
      * @param title Title of the page to be shared.
      * @param url URL of the page to be shared.
      * @param screenshot Screenshot of the page to be shared.
+     * @param extraIntentFlags Additional flags that should be added to the share intent.
      */
     private static void shareWithLastUsed(
-            Activity activity, String title, String url, Bitmap screenshot) {
+            Activity activity, String title, String url, Bitmap screenshot, int extraIntentFlags) {
         ComponentName component = getLastShareComponentName(activity);
         if (component == null) return;
-        Intent intent = getDirectShareIntentForComponent(title, url, screenshot, component);
+        Intent intent = getDirectShareIntentForComponent(
+                title, url, screenshot, component, extraIntentFlags);
         activity.startActivity(intent);
     }
 
@@ -150,8 +154,10 @@
         }
     }
 
-    private static Intent getShareIntent(String title, String url, Bitmap screenshot) {
+    private static Intent getShareIntent(String title, String url, Bitmap screenshot,
+            int extraIntentFlags) {
         Intent intent = new Intent(Intent.ACTION_SEND);
+        intent.addFlags(extraIntentFlags);
         intent.setType("text/plain");
         intent.putExtra(Intent.EXTRA_SUBJECT, title);
         intent.putExtra(Intent.EXTRA_TEXT, url);
@@ -160,8 +166,8 @@
     }
 
     private static Intent getDirectShareIntentForComponent(String title, String url,
-            Bitmap screenshot, ComponentName component) {
-        Intent intent = getShareIntent(title, url, screenshot);
+            Bitmap screenshot, ComponentName component, int extraIntentFlags) {
+        Intent intent = getShareIntent(title, url, screenshot, extraIntentFlags);
         intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
                 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
         intent.setComponent(component);
diff --git a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java
index 05608d3..0a5e8c5 100644
--- a/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java
+++ b/chrome/android/shell/java/src/org/chromium/chrome/shell/ChromeShellActivity.java
@@ -284,6 +284,7 @@
         return super.onKeyDown(keyCode, event);
     }
 
+    @SuppressWarnings("deprecation")
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         ChromeShellTab activeTab = getActiveTab();
@@ -322,7 +323,8 @@
             case R.id.share_menu_id:
             case R.id.direct_share_menu_id:
                 ShareHelper.share(item.getItemId() == R.id.direct_share_menu_id, this,
-                        activeTab.getTitle(), activeTab.getUrl(), null);
+                        activeTab.getTitle(), activeTab.getUrl(), null,
+                        Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                 return true;
             default:
                 return super.onOptionsItemSelected(item);
diff --git a/chrome/app/app-Info.plist b/chrome/app/app-Info.plist
index 3cd5f6a..b6fc276 100644
--- a/chrome/app/app-Info.plist
+++ b/chrome/app/app-Info.plist
@@ -324,6 +324,10 @@
 	<string>BrowserCrApplication</string>
 	<key>NSSupportsAutomaticGraphicsSwitching</key>
 	<true/>
+	<key>NSUserActivityTypes</key>
+	<array>
+		<string>NSUserActivityTypeBrowsingWeb</string>
+	</array>
 	<key>UTExportedTypeDeclarations</key>
 	<array>
 		<dict>
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd
index 06c5cf8..cfe9aef 100644
--- a/chrome/app/chromium_strings.grd
+++ b/chrome/app/chromium_strings.grd
@@ -1205,7 +1205,7 @@
 
       <!-- Contextual Search -->
       <message name="IDS_CONTEXTUAL_SEARCH_PROMO_DESCRIPTION" desc="Description of the Contextual Search feature.">
-        Enabling "Tap to Search" provides an easy way to search for terms on a web page by simply tapping on them.  The word tapped and surrounding page will be sent to Google.
+        “Touch to Search” provides an easy way to search for terms on a web page by simply touching on them.  The touched word and surrounding page will be sent to Google.
       </message>
       <message name="IDS_CONTEXTUAL_SEARCH_PROMO_OPTIN" desc="Text for the button the user clicks to opt in.">
         Yes, please
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index ee46a22..ff61f5e 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -14538,7 +14538,7 @@
     </message>
     <!-- Strings for notification shown when the Chromebook is added to Easy Unlock -->
     <message name="IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_TITLE" desc="Title for notification shown when this Chromebook is added to Easy Unlock as an additional Easy Unlock device.">
-      Easy unock is now enabled
+      Easy unlock is now enabled
     </message>
     <message name="IDS_EASY_UNLOCK_CHROMEBOOK_ADDED_NOTIFICATION_MESSAGE" desc="Message for the notification shown when this Chromebook is added to Easy Unlock as an additional Easy Unlock device.">
       You can start using your Android phone to unlock this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph>, too - no additional setup necessary.
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd
index f45570c..b6f2e50 100644
--- a/chrome/app/google_chrome_strings.grd
+++ b/chrome/app/google_chrome_strings.grd
@@ -1130,7 +1130,7 @@
 
       <!-- Contextual Search -->
       <message name="IDS_CONTEXTUAL_SEARCH_PROMO_DESCRIPTION" desc="Description of the Contextual Search feature.">
-        Enabling "Tap to Search" provides an easy way to search for terms on a web page by simply tapping on them.  The word tapped and surrounding page will be sent to Google.
+        “Touch to Search” provides an easy way to search for terms on a web page by simply touching on them.  The touched word and surrounding page will be sent to Google.
       </message>
       <message name="IDS_CONTEXTUAL_SEARCH_PROMO_OPTIN" desc="Text for the button the user clicks to opt in.">
         Yes, please
diff --git a/chrome/app/resources/locale_settings_chromiumos.grd b/chrome/app/resources/locale_settings_chromiumos.grd
index 8273021..6141a4f 100644
--- a/chrome/app/resources/locale_settings_chromiumos.grd
+++ b/chrome/app/resources/locale_settings_chromiumos.grd
@@ -208,7 +208,7 @@
       <!-- The default value for |WebPreference::standard_font_family_map| for
            Japanese script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_JAPANESE" use_name_for_id="true">
-        IPAPGothic
+        Noto Sans CJK Japanese
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
@@ -226,13 +226,13 @@
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Japanese script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_JAPANESE" use_name_for_id="true">
-        IPAPGothic
+        Noto Sans CJK Japanese
       </message>
 
      <!-- The default value for |WebPreference::standard_font_family_map| for
            Korean script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_KOREAN" use_name_for_id="true">
-        NanumGothic
+        Noto Sans CJK Korean
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
@@ -250,55 +250,55 @@
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Korean script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_KOREAN" use_name_for_id="true">
-        NanumGothic
+        Noto Sans CJK Korean
       </message>
 
       <!-- The default value for |WebPreference::standard_font_family_map| for
            Simplified Chinese script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Simplified Chinese
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
            Simplified Chinese script. -->
       <message name="IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Simplfieid Chinese
       </message>
 
       <!-- The default value for |WebPreference::serif_font_family_map| for
            Simplified Chinese script. -->
       <message name="IDS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Simplfieid Chinese
       </message>
 
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Simplified Chinese script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Simplfieid Chinese
       </message>
 
       <!-- The default value for |WebPreference::standard_font_family_map| for
            Traditional Chinese script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Traditional Chinese
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
            Traditional Chinese script. -->
       <message name="IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Traditional Chinese
       </message>
 
       <!-- The default value for |WebPreference::serif_font_family_map| for
            Traditional Chinese script. -->
       <message name="IDS_SERIF_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Traditional Chinese
       </message>
 
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Traditional Chinese script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        Droid Sans Fallback
+        Noto Sans CJK Traditional Chinese
       </message>
 
       <!-- The default value for |WebPreference::default_font_size| -->
diff --git a/chrome/app/resources/locale_settings_google_chromeos.grd b/chrome/app/resources/locale_settings_google_chromeos.grd
index 2901289..a553732 100644
--- a/chrome/app/resources/locale_settings_google_chromeos.grd
+++ b/chrome/app/resources/locale_settings_google_chromeos.grd
@@ -208,7 +208,7 @@
       <!-- The default value for |WebPreference::standard_font_family_map| for
            Japanese script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_JAPANESE" use_name_for_id="true">
-        MotoyaG04Gothic
+        Noto Sans CJK Japanese
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
@@ -226,13 +226,13 @@
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Japanese script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_JAPANESE" use_name_for_id="true">
-        MotoyaG04Gothic
+        Noto Sans CJK Japanese
       </message>
 
      <!-- The default value for |WebPreference::standard_font_family_map| for
            Korean script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_KOREAN" use_name_for_id="true">
-        NanumGothic
+        Noto Sans CJK Korean
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
@@ -250,19 +250,19 @@
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Korean script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_KOREAN" use_name_for_id="true">
-        NanumGothic
+        Noto Sans CJK Korean
       </message>
 
       <!-- The default value for |WebPreference::standard_font_family_map| for
            Simplified Chinese script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        MYingHeiGB18030
+        Noto Sans CJK Simplified Chinese
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
            Simplified Chinese script. -->
       <message name="IDS_FIXED_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        MYingHeiGB18030
+        Noto Sans CJK Simplified Chinese
       </message>
 
       <!-- The default value for |WebPreference::serif_font_family_map| for
@@ -274,19 +274,19 @@
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Simplified Chinese script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_SIMPLIFIED_HAN" use_name_for_id="true">
-        MYingHeiGB18030
+        Noto Sans CJK Simplified Chinese
       </message>
 
       <!-- The default value for |WebPreference::standard_font_family_map| for
            Traditional Chinese script. -->
       <message name="IDS_STANDARD_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        MYingHeiB5HK
+        Noto Sans CJK Traditional  Chinese
       </message>
 
       <!-- The default value for |WebPreference::fixed_font_family_map| for
            Traditional Chinese script. -->
       <message name="IDS_FIXED_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        MYingHeiB5HK
+        Noto Sans CJK Traditional  Chinese
       </message>
 
       <!-- The default value for |WebPreference::serif_font_family_map| for
@@ -298,7 +298,7 @@
       <!-- The default value for |WebPreference::sans_serif_font_family_map| for
            Traditional Chinese script.  -->
       <message name="IDS_SANS_SERIF_FONT_FAMILY_TRADITIONAL_HAN" use_name_for_id="true">
-        MYingHeiB5HK
+        Noto Sans CJK Traditional  Chinese
       </message>
 
       <!-- The default value for |WebPreference::default_font_size| -->
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_cros_ja.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_cros_ja.xtb
index 7d36881..819d457 100644
--- a/chrome/app/resources/platform_locale_settings/locale_settings_cros_ja.xtb
+++ b/chrome/app/resources/platform_locale_settings/locale_settings_cros_ja.xtb
@@ -1,17 +1,15 @@
 <?xml version="1.0" ?>
 <!DOCTYPE translationbundle>
 <translationbundle lang="ja">
+<translation id="IDS_STANDARD_FONT_FAMILY">Noto Sans CJK Japanese</translation>
+<translation id="IDS_SANS_SERIF_FONT_FAMILY">Noto Sans CJK Japanese</translation>
 <if expr="_google_chrome">
-  <translation id="IDS_STANDARD_FONT_FAMILY">MotoyaG04Gothic</translation>
   <translation id="IDS_FIXED_FONT_FAMILY">MotoyaG04GothicMono</translation>
   <translation id="IDS_SERIF_FONT_FAMILY">MotoyaG04Mincho</translation>
-  <translation id="IDS_SANS_SERIF_FONT_FAMILY">MotoyaG04Gothic</translation>
 </if>
 <if expr="not _google_chrome">
-  <translation id="IDS_STANDARD_FONT_FAMILY">IPAPGothic</translation>
   <translation id="IDS_FIXED_FONT_FAMILY">IPAGothic</translation>
   <translation id="IDS_SERIF_FONT_FAMILY">IPAPMincho</translation>
-  <translation id="IDS_SANS_SERIF_FONT_FAMILY">IPAPGothic</translation>
 </if>
 <translation id="IDS_MINIMUM_FONT_SIZE">10</translation>
 <translation id="IDS_MINIMUM_LOGICAL_FONT_SIZE">10</translation>
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_cros_ko.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_cros_ko.xtb
index cb0db2a..a696d89 100644
--- a/chrome/app/resources/platform_locale_settings/locale_settings_cros_ko.xtb
+++ b/chrome/app/resources/platform_locale_settings/locale_settings_cros_ko.xtb
@@ -2,10 +2,10 @@
 <!DOCTYPE translationbundle>
 <translationbundle lang="ko">
 <!-- TODO(jungshik): remove this line once we fix bug 14691 -->
-<translation id="IDS_STANDARD_FONT_FAMILY">NanumGothic</translation>
+<translation id="IDS_STANDARD_FONT_FAMILY">Noto Sans CJK Korean</translation>
 <translation id="IDS_FIXED_FONT_FAMILY">Monospace</translation>
 <translation id="IDS_SERIF_FONT_FAMILY">NanumMyeongjo</translation>
-<translation id="IDS_SANS_SERIF_FONT_FAMILY">NanumGothic</translation>
+<translation id="IDS_SANS_SERIF_FONT_FAMILY">Noto Sans CJK Korean</translation>
 <translation id="IDS_MINIMUM_FONT_SIZE">10</translation>
 <translation id="IDS_MINIMUM_LOGICAL_FONT_SIZE">10</translation>
 </translationbundle>
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-CN.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-CN.xtb
index cfd9f1e..1a98e1d 100644
--- a/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-CN.xtb
+++ b/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-CN.xtb
@@ -1,16 +1,14 @@
 <?xml version="1.0" ?>
 <!DOCTYPE translationbundle>
 <translationbundle lang="zh-CN">
+<translation id="IDS_STANDARD_FONT_FAMILY">Noto Sans CJK Simplified Chinese</translation>
+<translation id="IDS_FIXED_FONT_FAMILY">Noto Sans CJK Simplified Chinese</translation>
+<translation id="IDS_SANS_SERIF_FONT_FAMILY">Noto Sans CJK Simplified Chinese</translation>
 <if expr="_google_chrome">
-  <translation id="IDS_STANDARD_FONT_FAMILY">MYingHeiGB18030</translation>
-  <translation id="IDS_FIXED_FONT_FAMILY">MYingHeiGB18030</translation>
   <translation id="IDS_SERIF_FONT_FAMILY">MSung GB18030</translation>
-  <translation id="IDS_SANS_SERIF_FONT_FAMILY">MYingHeiGB18030</translation>
 </if>
 <if expr="not _google_chrome">
-  <translation id="IDS_STANDARD_FONT_FAMILY">Droid Sans Fallback</translation>
-  <translation id="IDS_FIXED_FONT_FAMILY">Droid Sans Fallback</translation>
-  <translation id="IDS_SANS_SERIF_FONT_FAMILY">Droid Sans Fallback</translation>
+  <translation id="IDS_SERIF_FONT_FAMILY">Noto Sans CJK Simplified Chinese</translation>
 </if>
 <translation id="IDS_MINIMUM_FONT_SIZE">12</translation>
 <translation id="IDS_MINIMUM_LOGICAL_FONT_SIZE">12</translation>
diff --git a/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-TW.xtb b/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-TW.xtb
index 74e2a1d..00e9094 100644
--- a/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-TW.xtb
+++ b/chrome/app/resources/platform_locale_settings/locale_settings_cros_zh-TW.xtb
@@ -1,16 +1,14 @@
 <?xml version="1.0" ?>
 <!DOCTYPE translationbundle>
 <translationbundle lang="zh-TW">
+<translation id="IDS_STANDARD_FONT_FAMILY">Noto Sans CJK Traditional Chinese</translation>
+<translation id="IDS_FIXED_FONT_FAMILY">Noto Sans CJK Traditional Chinese</translation>
+<translation id="IDS_SANS_SERIF_FONT_FAMILY">Noto Sans CJK Traditional Chinese</translation>
 <if expr="_google_chrome">
-  <translation id="IDS_STANDARD_FONT_FAMILY">MYingHeiB5HK</translation>
-  <translation id="IDS_FIXED_FONT_FAMILY">MYingHeiB5HK</translation>
   <translation id="IDS_SERIF_FONT_FAMILY">MSung B5HK</translation>
-  <translation id="IDS_SANS_SERIF_FONT_FAMILY">MYingHeiB5HK</translation>
 </if>
 <if expr="not _google_chrome">
-  <translation id="IDS_STANDARD_FONT_FAMILY">Droid Sans Fallback</translation>
-  <translation id="IDS_FIXED_FONT_FAMILY">Droid Sans Fallback</translation>
-  <translation id="IDS_SANS_SERIF_FONT_FAMILY">Droid Sans Fallback</translation>
+<translation id="IDS_SERIF_FONT_FAMILY">Noto Sans CJK Traditional Chinese</translation>
 </if>
 <translation id="IDS_MINIMUM_FONT_SIZE">12</translation>
 <translation id="IDS_MINIMUM_LOGICAL_FONT_SIZE">12</translation>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 2a87d86..881c154 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1119,7 +1119,7 @@
     "enable-password-generation",
     IDS_FLAGS_ENABLE_PASSWORD_GENERATION_NAME,
     IDS_FLAGS_ENABLE_PASSWORD_GENERATION_DESCRIPTION,
-    kOsWin | kOsLinux | kOsCrOS,
+    kOsWin | kOsLinux | kOsCrOS | kOsMac,
     ENABLE_DISABLE_VALUE_TYPE(autofill::switches::kEnablePasswordGeneration,
                               autofill::switches::kDisablePasswordGeneration)
   },
diff --git a/chrome/browser/android/most_visited_sites.cc b/chrome/browser/android/most_visited_sites.cc
index e13597c..7b71164 100644
--- a/chrome/browser/android/most_visited_sites.cc
+++ b/chrome/browser/android/most_visited_sites.cc
@@ -24,8 +24,11 @@
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/search/suggestions/suggestions_service_factory.h"
 #include "chrome/browser/search/suggestions/suggestions_source.h"
+#include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/thumbnails/thumbnail_list_source.h"
 #include "components/suggestions/suggestions_service.h"
+#include "components/suggestions/suggestions_utils.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/browser/url_data_source.h"
@@ -46,6 +49,7 @@
 using suggestions::SuggestionsProfile;
 using suggestions::SuggestionsService;
 using suggestions::SuggestionsServiceFactory;
+using suggestions::SyncState;
 
 namespace {
 
@@ -171,6 +175,18 @@
     counter->Add(position);
 }
 
+// Return the current SyncState for use with the SuggestionsService.
+SyncState GetSyncState(Profile* profile) {
+  ProfileSyncService* sync =
+      ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile);
+  if (!sync)
+    return SyncState::SYNC_OR_HISTORY_SYNC_DISABLED;
+  return suggestions::GetSyncState(
+      sync->IsSyncEnabledAndLoggedIn(),
+      sync->sync_initialized(),
+      sync->GetActiveDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES));
+}
+
 }  // namespace
 
 MostVisitedSites::MostVisitedSites(Profile* profile)
@@ -182,9 +198,21 @@
   content::URLDataSource::Add(profile_,
                               new suggestions::SuggestionsSource(profile_));
   content::URLDataSource::Add(profile_, new ThumbnailListSource(profile_));
+
+  // Register this class as an observer to the sync service. It is important to
+  // be notified of changes in the sync state such as initialization, sync
+  // being enabled or disabled, etc.
+  ProfileSyncService* profile_sync_service =
+      ProfileSyncServiceFactory::GetForProfile(profile_);
+  if (profile_sync_service)
+    profile_sync_service->AddObserver(this);
 }
 
 MostVisitedSites::~MostVisitedSites() {
+  ProfileSyncService* profile_sync_service =
+      ProfileSyncServiceFactory::GetForProfile(profile_);
+  if (profile_sync_service && profile_sync_service->HasObserver(this))
+    profile_sync_service->RemoveObserver(this);
 }
 
 void MostVisitedSites::Destroy(JNIEnv* env, jobject obj) {
@@ -230,11 +258,13 @@
   std::string url_string = ConvertJavaStringToUTF8(env, url);
   scoped_refptr<TopSites> top_sites(profile_->GetTopSites());
 
-  // If the Suggestions service is enabled, create a callback to fetch a
-  // server thumbnail from it, in case the local thumbnail is not found.
+  // If the Suggestions service is enabled and in use, create a callback to
+  // fetch a server thumbnail from it, in case the local thumbnail is not found.
   SuggestionsService* suggestions_service =
       SuggestionsServiceFactory::GetForProfile(profile_);
-  base::Closure lookup_failed_callback = suggestions_service ?
+  bool use_suggestions_service = suggestions_service &&
+      mv_source_ == SUGGESTIONS_SERVICE;
+  base::Closure lookup_failed_callback = use_suggestions_service ?
       base::Bind(&MostVisitedSites::GetSuggestionsThumbnailOnUIThread,
                  weak_ptr_factory_.GetWeakPtr(),
                  suggestions_service, url_string,
@@ -317,6 +347,13 @@
   }
 }
 
+void MostVisitedSites::OnStateChanged() {
+  // There have been changes to the sync state. This class cares about a few
+  // (just initialized, enabled/disabled or history sync state changed). Re-run
+  // the query code which will use the proper state.
+  QueryMostVisitedURLs();
+}
+
 // static
 bool MostVisitedSites::Register(JNIEnv* env) {
   return RegisterNativesImpl(env);
@@ -328,6 +365,7 @@
   if (suggestions_service) {
     // Suggestions service is enabled, initiate a query.
     suggestions_service->FetchSuggestionsData(
+        GetSyncState(profile_),
         base::Bind(
           &MostVisitedSites::OnSuggestionsProfileAvailable,
           weak_ptr_factory_.GetWeakPtr(),
diff --git a/chrome/browser/android/most_visited_sites.h b/chrome/browser/android/most_visited_sites.h
index 39ecceb..4a24ad7 100644
--- a/chrome/browser/android/most_visited_sites.h
+++ b/chrome/browser/android/most_visited_sites.h
@@ -12,6 +12,7 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/history/history_types.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/profile_sync_service_observer.h"
 #include "components/suggestions/proto/suggestions.pb.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
@@ -21,7 +22,8 @@
 }
 
 // Provides the list of most visited sites and their thumbnails to Java.
-class MostVisitedSites : public content::NotificationObserver {
+class MostVisitedSites : public ProfileSyncServiceObserver,
+                         public content::NotificationObserver {
  public:
   typedef base::Callback<
       void(base::android::ScopedJavaGlobalRef<jobject>* bitmap,
@@ -47,6 +49,9 @@
                        const content::NotificationSource& source,
                        const content::NotificationDetails& details) OVERRIDE;
 
+  // ProfileSyncServiceObserver implementation.
+  virtual void OnStateChanged() OVERRIDE;
+
   // Registers JNI methods.
   static bool Register(JNIEnv* env);
 
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index 0e40ea0..6d536f3 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -306,6 +306,17 @@
       did_finish_load);
 }
 
+void TabAndroid::OnWebContentsInstantSupportDisabled(
+    const content::WebContents* contents) {
+  DCHECK(contents);
+  if (web_contents() != contents)
+    return;
+
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_Tab_onWebContentsInstantSupportDisabled(env,
+                                               weak_java_tab_.get(env).obj());
+}
+
 void TabAndroid::Observe(int type,
                          const content::NotificationSource& source,
                          const content::NotificationDetails& details) {
@@ -371,6 +382,7 @@
   WindowAndroidHelper::FromWebContents(web_contents())->
       SetWindowAndroid(content_view_core->GetWindowAndroid());
   CoreTabHelper::FromWebContents(web_contents())->set_delegate(this);
+  SearchTabHelper::FromWebContents(web_contents())->set_delegate(this);
   web_contents_delegate_.reset(
       new chrome::android::ChromeWebContentsDelegateAndroid(
           env, jweb_contents_delegate));
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index d09aa93..c25d16e 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -13,6 +13,7 @@
 #include "base/strings/string16.h"
 #include "chrome/browser/sessions/session_id.h"
 #include "chrome/browser/sync/glue/synced_tab_delegate_android.h"
+#include "chrome/browser/ui/search/search_tab_helper_delegate.h"
 #include "chrome/browser/ui/tab_contents/core_tab_helper_delegate.h"
 #include "chrome/browser/ui/toolbar/toolbar_model.h"
 #include "content/public/browser/notification_observer.h"
@@ -42,6 +43,7 @@
 }
 
 class TabAndroid : public CoreTabHelperDelegate,
+                   public SearchTabHelperDelegate,
                    public content::NotificationObserver {
  public:
   enum TabLoadStatus {
@@ -111,6 +113,10 @@
                                bool did_start_load,
                                bool did_finish_load) OVERRIDE;
 
+  // Overridden from SearchTabHelperDelegate:
+  virtual void OnWebContentsInstantSupportDisabled(
+      const content::WebContents* web_contents) OVERRIDE;
+
   // NotificationObserver -----------------------------------------------------
   virtual void Observe(int type,
                        const content::NotificationSource& source,
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 57fb281..6c5f2bb 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -1546,6 +1546,36 @@
       WorkAreaChanged());
 }
 
+- (BOOL)application:(NSApplication*)application
+    willContinueUserActivityWithType:(NSString*)userActivityType {
+  return [userActivityType isEqualToString:NSUserActivityTypeBrowsingWeb];
+}
+
+- (BOOL)application:(NSApplication*)application
+    continueUserActivity:(NSUserActivity*)userActivity
+      restorationHandler:(void (^)(NSArray*))restorationHandler {
+  if (![userActivity.activityType
+          isEqualToString:NSUserActivityTypeBrowsingWeb]) {
+    return NO;
+  }
+
+  NSURL* url = userActivity.webPageURL;
+  if (!url)
+    return NO;
+
+  GURL gurl(base::SysNSStringToUTF8([url absoluteString]));
+  std::vector<GURL> gurlVector;
+  gurlVector.push_back(gurl);
+
+  [self openUrls:gurlVector];
+  return YES;
+}
+
+- (void)application:(NSApplication*)application
+    didFailToContinueUserActivityWithType:(NSString*)userActivityType
+                                    error:(NSError*)error {
+}
+
 @end  // @implementation AppController
 
 //---------------------------------------------------------------------------
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index b7967f8..942daad 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/chrome_browser_main_linux.h"
 
+#include <fontconfig/fontconfig.h>
+
 #include "chrome/browser/browser_process.h"
 #include "components/breakpad/app/breakpad_linux.h"
 #include "components/metrics/metrics_service.h"
@@ -22,6 +24,15 @@
 ChromeBrowserMainPartsLinux::~ChromeBrowserMainPartsLinux() {
 }
 
+void ChromeBrowserMainPartsLinux::ToolkitInitialized() {
+  // Explicitly initialize Fontconfig early on to prevent races later due to
+  // implicit initialization in response to threads' first calls to Fontconfig:
+  // http://crbug.com/404311
+  FcInit();
+
+  ChromeBrowserMainPartsPosix::ToolkitInitialized();
+}
+
 void ChromeBrowserMainPartsLinux::PreProfileInit() {
 #if !defined(OS_CHROMEOS)
   // Needs to be called after we have chrome::DIR_USER_DATA and
diff --git a/chrome/browser/chrome_browser_main_linux.h b/chrome/browser/chrome_browser_main_linux.h
index 37f35ce..9d9a92a 100644
--- a/chrome/browser/chrome_browser_main_linux.h
+++ b/chrome/browser/chrome_browser_main_linux.h
@@ -17,6 +17,7 @@
   virtual ~ChromeBrowserMainPartsLinux();
 
   // ChromeBrowserMainParts overrides.
+  virtual void ToolkitInitialized() OVERRIDE;
   virtual void PreProfileInit() OVERRIDE;
   virtual void PostProfileInit() OVERRIDE;
 
diff --git a/chrome/browser/chromeos/boot_times_loader.cc b/chrome/browser/chromeos/boot_times_loader.cc
index eb4633e..1e5c22e 100644
--- a/chrome/browser/chromeos/boot_times_loader.cc
+++ b/chrome/browser/chromeos/boot_times_loader.cc
@@ -146,7 +146,7 @@
 }
 
 std::string BootTimesLoader::Stats::SerializeToString() const {
-  if (uptime_.empty() || disk_.empty())
+  if (uptime_.empty() && disk_.empty())
     return std::string();
   base::DictionaryValue dictionary;
   dictionary.SetString(kUptime, uptime_);
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
index 094e5ff..5540993 100644
--- a/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/private_api_misc.cc
@@ -62,7 +62,7 @@
 }
 
 std::vector<linked_ptr<api::file_browser_private::ProfileInfo> >
-GetLoggedInProfileInfoList(content::WebContents* contents) {
+GetLoggedInProfileInfoList() {
   DCHECK(user_manager::UserManager::IsInitialized());
   const std::vector<Profile*>& profiles =
       g_browser_process->profile_manager()->GetLoadedProfiles();
@@ -89,18 +89,6 @@
     // TODO(hirono): Remove the property from the profile_info.
     profile_info->is_current_profile = true;
 
-    // Make an icon URL of the profile.
-    if (contents) {
-      const gfx::Image& image =
-          ash::GetAvatarImageForContext(contents->GetBrowserContext());
-      const gfx::ImageSkia& skia = image.AsImageSkia();
-      profile_info->profile_image.reset(
-          new api::file_browser_private::ImageSet);
-      profile_info->profile_image->scale1x_url =
-          webui::GetBitmapDataUrl(skia.GetRepresentation(1.0f).sk_bitmap());
-      profile_info->profile_image->scale2x_url =
-          webui::GetBitmapDataUrl(skia.GetRepresentation(2.0f).sk_bitmap());
-    }
     result_profiles.push_back(profile_info);
   }
 
@@ -380,7 +368,7 @@
 
 bool FileBrowserPrivateGetProfilesFunction::RunSync() {
   const std::vector<linked_ptr<api::file_browser_private::ProfileInfo> >&
-      profiles = GetLoggedInProfileInfoList(GetAssociatedWebContents());
+      profiles = GetLoggedInProfileInfoList();
 
   // Obtains the display profile ID.
   apps::AppWindow* const app_window = GetCurrentAppWindow(this);
@@ -404,7 +392,7 @@
   using api::file_browser_private::VisitDesktop::Params;
   const scoped_ptr<Params> params(Params::Create(*args_));
   const std::vector<linked_ptr<api::file_browser_private::ProfileInfo> >&
-      profiles = GetLoggedInProfileInfoList(GetAssociatedWebContents());
+      profiles = GetLoggedInProfileInfoList();
 
   chrome::MultiUserWindowManager* const window_manager =
       chrome::MultiUserWindowManager::GetInstance();
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 31c1c38..1c4cb33 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -1221,24 +1221,6 @@
 
 // Slow tests are disabled on debug build. http://crbug.com/327719
 #if !defined(NDEBUG)
-#define MAYBE_PRE_Badge DISABLED_PRE_Badge
-#define MAYBE_Badge DISABLED_Badge
-#else
-#define MAYBE_PRE_Badge PRE_Badge
-#define MAYBE_Badge Badge
-#endif
-IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_PRE_Badge) {
-  AddAllUsers();
-}
-
-IN_PROC_BROWSER_TEST_F(MultiProfileFileManagerBrowserTest, MAYBE_Badge) {
-  // Test the profile badge to be correctly shown and hidden.
-  set_test_case_name("multiProfileBadge");
-  StartTest();
-}
-
-// Slow tests are disabled on debug build. http://crbug.com/327719
-#if !defined(NDEBUG)
 #define MAYBE_PRE_VisitDesktopMenu DISABLED_PRE_VisitDesktopMenu
 #define MAYBE_VisitDesktopMenu DISABLED_VisitDesktopMenu
 #else
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index 7e6aeae..02757ab 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -153,6 +153,7 @@
     ::switches::kDisableWebRtcHWDecoding,
     ::switches::kDisableWebRtcHWEncoding,
     ::switches::kEnableWebRtcHWVp8Encoding,
+    ::switches::kEnableWebRtcHWH264Encoding,
 #endif
     ::switches::kDisableVaapiAcceleratedVideoEncode,
 #if defined(USE_OZONE)
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
index 7650d1a..d24d75c 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -164,7 +164,7 @@
 }
 
 void AutoEnrollmentController::StartClient(
-    const std::vector<std::string>& state_keys) {
+    const std::vector<std::string>& state_keys, bool first_boot) {
   policy::BrowserPolicyConnectorChromeOS* connector =
       g_browser_process->platform_part()->browser_policy_connector_chromeos();
   policy::DeviceManagementService* service =
@@ -185,7 +185,8 @@
   std::string device_id;
   if (GetMode() == MODE_FORCED_RE_ENROLLMENT) {
     retrieve_device_state = true;
-    device_id = state_keys.empty() ? std::string() : state_keys.front();
+    if (!state_keys.empty() && !first_boot)
+      device_id = state_keys.front();
   } else {
     device_id = policy::DeviceCloudPolicyManagerChromeOS::GetMachineID();
   }
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h
index 67f31d5..cb7b2ee 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h
@@ -75,7 +75,7 @@
       DeviceSettingsService::OwnershipStatus status);
 
   // Starts the auto-enrollment client.
-  void StartClient(const std::vector<std::string>& state_keys);
+  void StartClient(const std::vector<std::string>& state_keys, bool first_boot);
 
   // Sets |state_| and notifies |progress_callbacks_|.
   void UpdateState(policy::AutoEnrollmentState state);
diff --git a/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc b/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc
index 4eecbd9..a6eff90 100644
--- a/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.cc
@@ -126,28 +126,16 @@
     }
   }
 
-  if (new_recommended_locales.empty()) {
-    // There are no recommended locales.
-    PublicSessionRecommendedLocaleMap::iterator it =
-        public_session_recommended_locales_.find(user_id);
-    if (it != public_session_recommended_locales_.end()) {
-      // If there previously were recommended locales, remove them from
-      // |public_session_recommended_locales_| and notify the UI.
-      public_session_recommended_locales_.erase(it);
-      SetPublicSessionLocales(user_id, &new_recommended_locales);
-    }
-    return;
-  }
-
-  // There are recommended locales.
   std::vector<std::string>& recommended_locales =
       public_session_recommended_locales_[user_id];
-  if (new_recommended_locales != recommended_locales) {
-    // If the list of recommended locales has changed, update
-    // |public_session_recommended_locales_| and notify the UI.
+
+  if (new_recommended_locales != recommended_locales)
+    SetPublicSessionLocales(user_id, new_recommended_locales);
+
+  if (new_recommended_locales.empty())
+    public_session_recommended_locales_.erase(user_id);
+  else
     recommended_locales = new_recommended_locales;
-    SetPublicSessionLocales(user_id, &new_recommended_locales);
-  }
 }
 
 void ChromeUserSelectionScreen::SetPublicSessionDisplayName(
@@ -164,29 +152,31 @@
 
 void ChromeUserSelectionScreen::SetPublicSessionLocales(
     const std::string& user_id,
-    const std::vector<std::string>* recommended_locales) {
+    const std::vector<std::string>& recommended_locales) {
   if (!handler_initialized_)
     return;
 
   // Construct the list of available locales. This list consists of the
   // recommended locales, followed by all others.
-  scoped_ptr<base::ListValue> locales =
-      GetUILanguageList(recommended_locales, std::string());
+  scoped_ptr<base::ListValue> available_locales =
+      GetUILanguageList(&recommended_locales, std::string());
 
-  // Set the initially selected locale. If the list of recommended locales is
-  // not empty, select its first entry. Otherwise, select the current UI locale.
-  const std::string& default_locale = recommended_locales->empty() ?
-      g_browser_process->GetApplicationLocale() : recommended_locales->front();
+  // Set the initially selected locale to the first recommended locale that is
+  // actually available or the current UI locale if none of them are available.
+  const std::string default_locale = FindMostRelevantLocale(
+      recommended_locales,
+      *available_locales.get(),
+      g_browser_process->GetApplicationLocale());
 
   // Set a flag to indicate whether the list of recommended locales contains at
   // least two entries. This is used to decide whether the public session pod
   // expands to its basic form (for zero or one recommended locales) or the
   // advanced form (two or more recommended locales).
-  const bool two_or_more_recommended_locales = recommended_locales->size() >= 2;
+  const bool two_or_more_recommended_locales = recommended_locales.size() >= 2;
 
   // Notify the UI.
   handler_->SetPublicSessionLocales(user_id,
-                                    locales.Pass(),
+                                    available_locales.Pass(),
                                     default_locale,
                                     two_or_more_recommended_locales);
 }
diff --git a/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h b/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h
index 46e71ff..db17645 100644
--- a/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h
+++ b/chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h
@@ -52,7 +52,7 @@
   // of the |recommended_locales| followed by all other available locales.
   void SetPublicSessionLocales(
       const std::string& user_id,
-      const std::vector<std::string>* recommended_locales);
+      const std::vector<std::string>& recommended_locales);
 
   bool handler_initialized_;
 
diff --git a/chrome/browser/chromeos/login/screens/user_selection_screen.cc b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
index 41c3024..be0c782 100644
--- a/chrome/browser/chromeos/login/screens/user_selection_screen.cc
+++ b/chrome/browser/chromeos/login/screens/user_selection_screen.cc
@@ -4,8 +4,6 @@
 
 #include "chrome/browser/chromeos/login/screens/user_selection_screen.h"
 
-#include <vector>
-
 #include "ash/shell.h"
 #include "base/location.h"
 #include "base/logging.h"
@@ -66,23 +64,27 @@
   }
 
   std::vector<std::string> kEmptyRecommendedLocales;
-  const std::vector<std::string>* recommended_locales =
+  const std::vector<std::string>& recommended_locales =
       public_session_recommended_locales ?
-          public_session_recommended_locales : &kEmptyRecommendedLocales;
+          *public_session_recommended_locales : kEmptyRecommendedLocales;
 
-  // Set |kKeyInitialLocales| to the list of available locales. This list
-  // consists of the recommended locales, followed by all others.
-  user_dict->Set(
-      kKeyInitialLocales,
-      GetUILanguageList(recommended_locales, std::string()).release());
+  // Construct the list of available locales. This list consists of the
+  // recommended locales, followed by all others.
+  scoped_ptr<base::ListValue> available_locales =
+      GetUILanguageList(&recommended_locales, std::string());
 
-  // Set |kKeyInitialLocale| to the initially selected locale. If the list of
-  // recommended locales is not empty, select its first entry. Otherwise,
-  // select the current UI locale.
-  user_dict->SetString(kKeyInitialLocale,
-                       recommended_locales->empty() ?
-                           g_browser_process->GetApplicationLocale() :
-                           recommended_locales->front());
+  // Select the the first recommended locale that is actually available or the
+  // current UI locale if none of them are available.
+  const std::string selected_locale = FindMostRelevantLocale(
+      recommended_locales,
+      *available_locales.get(),
+      g_browser_process->GetApplicationLocale());
+
+  // Set |kKeyInitialLocales| to the list of available locales.
+  user_dict->Set(kKeyInitialLocales, available_locales.release());
+
+  // Set |kKeyInitialLocale| to the initially selected locale.
+  user_dict->SetString(kKeyInitialLocale, selected_locale);
 
   // Set |kKeyInitialMultipleRecommendedLocales| to indicate whether the list
   // of recommended locales contains at least two entries. This is used to
@@ -90,7 +92,7 @@
   // or one recommended locales) or the advanced form (two or more recommended
   // locales).
   user_dict->SetBoolean(kKeyInitialMultipleRecommendedLocales,
-                        recommended_locales->size() >= 2);
+                        recommended_locales.size() >= 2);
 
   // Set |kKeyInitialKeyboardLayout| to the current keyboard layout. This
   // value will be used temporarily only because the UI immediately requests a
@@ -362,6 +364,9 @@
 void UserSelectionScreen::SetAuthType(
     const std::string& username,
     ScreenlockBridge::LockHandler::AuthType auth_type) {
+  DCHECK(GetAuthType(username) !=
+             ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD ||
+         auth_type == ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD);
   user_auth_type_map_[username] = auth_type;
 }
 
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index 32aab49..254ef61 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -218,13 +218,7 @@
       // Users with a policy that prevents them being added to a session will be
       // shown in login UI but will be grayed out.
       // Same applies to owner account (see http://crbug.com/385034).
-      if (check == MultiProfileUserController::ALLOWED ||
-          check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
-          check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY ||
-          check ==
-              MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED) {
-        result.push_back(*it);
-      }
+      result.push_back(*it);
     }
   }
 
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index 077d915..ec2803b 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -128,12 +128,12 @@
 #include "net/url_request/url_request_status.h"
 #include "policy/policy_constants.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/icu/source/common/unicode/locid.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/views/widget/widget.h"
 #include "url/gurl.h"
-//#include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace em = enterprise_management;
 
@@ -190,6 +190,9 @@
   "fr",
   "nl",
 };
+const char* kInvalidRecommendedLocale[] = {
+  "xx",
+};
 const char kPublicSessionLocale[] = "de";
 const char kPublicSessionInputMethodIDTemplate[] = "_comp_ime_%sxkb:de:neo:ger";
 
@@ -377,23 +380,6 @@
   return user_manager::UserManager::Get()->IsSessionStarted();
 }
 
-// GetKeyboardLayoutsForLocale() posts a task to a background task runner. This
-// method flushes that task runner and the current thread's message loop to
-// ensure that GetKeyboardLayoutsForLocale() is finished.
-void WaitForGetKeyboardLayoutsForLocaleToFinish() {
-  base::SequencedWorkerPool* worker_pool =
-      content::BrowserThread::GetBlockingPool();
-   scoped_refptr<base::SequencedTaskRunner> background_task_runner =
-       worker_pool->GetSequencedTaskRunner(
-           worker_pool->GetNamedSequenceToken(kSequenceToken));
-  base::RunLoop run_loop;
-  background_task_runner->PostTaskAndReply(FROM_HERE,
-                                           base::Bind(&base::DoNothing),
-                                           run_loop.QuitClosure());
-  run_loop.Run();
-  base::RunLoop().RunUntilIdle();
-}
-
 }  // namespace
 
 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest,
@@ -460,6 +446,9 @@
   virtual void SetUpOnMainThread() OVERRIDE {
     DevicePolicyCrosBrowserTest::SetUpOnMainThread();
 
+    initial_locale_ = g_browser_process->GetApplicationLocale();
+    initial_language_ = l10n_util::GetLanguage(initial_locale_);
+
     content::WindowedNotificationObserver(
         chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
         content::NotificationService::AllSources()).Wait();
@@ -655,6 +644,47 @@
     WaitForDisplayName(user_id_1_, kDisplayName1);
   }
 
+  void ExpandPublicSessionPod(bool expect_advanced) {
+    bool advanced = false;
+    // Click on the pod to expand it.
+    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+        contents_,
+        base::StringPrintf(
+            "var pod ="
+            "    document.getElementById('pod-row').getPodWithUsername_('%s');"
+            "pod.click();"
+            "domAutomationController.send(pod.classList.contains('advanced'));",
+            user_id_1_.c_str()),
+        &advanced));
+    // Verify that the pod expanded to its basic/advanced form, as expected.
+    EXPECT_EQ(expect_advanced, advanced);
+
+    // Verify that the construction of the pod's language list did not affect
+    // the current ICU locale.
+    EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
+  }
+
+  // GetKeyboardLayoutsForLocale() posts a task to a background task runner.
+  // This method flushes that task runner and the current thread's message loop
+  // to ensure that GetKeyboardLayoutsForLocale() is finished.
+  void WaitForGetKeyboardLayoutsForLocaleToFinish() {
+    base::SequencedWorkerPool* worker_pool =
+        content::BrowserThread::GetBlockingPool();
+     scoped_refptr<base::SequencedTaskRunner> background_task_runner =
+         worker_pool->GetSequencedTaskRunner(
+             worker_pool->GetNamedSequenceToken(kSequenceToken));
+    base::RunLoop run_loop;
+    background_task_runner->PostTaskAndReply(FROM_HERE,
+                                             base::Bind(&base::DoNothing),
+                                             run_loop.QuitClosure());
+    run_loop.Run();
+    base::RunLoop().RunUntilIdle();
+
+    // Verify that the construction of the keyboard layout list did not affect
+    // the current ICU locale.
+    EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
+  }
+
   void StartLogin(const std::string& locale,
                   const std::string& input_method) {
     // Start login into the device-local account.
@@ -699,6 +729,9 @@
   const std::string user_id_2_;
   const std::string public_session_input_method_id_;
 
+  std::string initial_locale_;
+  std::string initial_language_;
+
   scoped_ptr<base::RunLoop> run_loop_;
 
   UserPolicyBuilder device_local_account_policy_;
@@ -1395,26 +1428,12 @@
 };
 
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleNoSwitch) {
-  const std::string initial_locale = g_browser_process->GetApplicationLocale();
-
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
 
   WaitForPolicy();
 
-  // Click on the pod to expand it. Verify that the pod expands to its basic
-  // form as there are no recommended locales.
-  bool advanced = false;
-  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      contents_,
-      base::StringPrintf(
-          "var pod ="
-          "    document.getElementById('pod-row').getPodWithUsername_('%s');"
-          "pod.click();"
-          "domAutomationController.send(pod.classList.contains('advanced'));",
-          user_id_1_.c_str()),
-      &advanced));
-  EXPECT_FALSE(advanced);
+  ExpandPublicSessionPod(false);
 
   // Click the enter button to start the session.
   ASSERT_TRUE(content::ExecuteScript(
@@ -1428,7 +1447,8 @@
 
   // Verify that the locale has not changed and the first keyboard layout
   // applicable to the locale was chosen.
-  EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(initial_locale_, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
   VerifyKeyboardLayoutMatchesLocale();
 }
 
@@ -1438,22 +1458,11 @@
 
   WaitForPolicy();
 
-  // Click on the pod to expand it. Verify that the pod expands to its basic
-  // form as there are no recommended locales.
-  bool advanced = false;
-  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      contents_,
-      base::StringPrintf(
-          "var pod ="
-          "    document.getElementById('pod-row').getPodWithUsername_('%s');"
-          "pod.click();"
-          "domAutomationController.send(pod.classList.contains('advanced'));",
-          user_id_1_.c_str()),
-      &advanced));
-  EXPECT_FALSE(advanced);
+  ExpandPublicSessionPod(false);
 
   // Click the link that switches the pod to its advanced form. Verify that the
   // pod switches from basic to advanced.
+  bool advanced = false;
   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
       contents_,
       base::StringPrintf(
@@ -1498,6 +1507,8 @@
 
   // Verify that the locale and keyboard layout have been applied.
   EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
+            icu::Locale::getDefault().getLanguage());
   EXPECT_EQ(public_session_input_method_id_,
             chromeos::input_method::InputMethodManager::Get()->
                 GetCurrentInputMethod().id());
@@ -1512,19 +1523,7 @@
 
   WaitForPolicy();
 
-  // Click on the pod to expand it. Verify that the pod expands to its basic
-  // form as there is only one recommended locale.
-  bool advanced = false;
-  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      contents_,
-      base::StringPrintf(
-          "var pod ="
-          "    document.getElementById('pod-row').getPodWithUsername_('%s');"
-          "pod.click();"
-          "domAutomationController.send(pod.classList.contains('advanced'));",
-          user_id_1_.c_str()),
-      &advanced));
-  EXPECT_FALSE(advanced);
+  ExpandPublicSessionPod(false);
 
   // Click the enter button to start the session.
   ASSERT_TRUE(content::ExecuteScript(
@@ -1540,6 +1539,8 @@
   // layout applicable to the locale was chosen.
   EXPECT_EQ(kSingleRecommendedLocale[0],
             g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(kSingleRecommendedLocale[0]),
+            icu::Locale::getDefault().getLanguage());
   VerifyKeyboardLayoutMatchesLocale();
 }
 
@@ -1552,19 +1553,7 @@
 
   WaitForPolicy();
 
-  // Click on the pod to expand it. Verify that the pod expands to its advanced
-  // form directly as there are two or more recommended locales.
-  bool advanced = false;
-  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
-      contents_,
-      base::StringPrintf(
-          "var pod ="
-          "    document.getElementById('pod-row').getPodWithUsername_('%s');"
-          "pod.click();"
-          "domAutomationController.send(pod.classList.contains('advanced'));",
-          user_id_1_.c_str()),
-      &advanced));
-  EXPECT_TRUE(advanced);
+  ExpandPublicSessionPod(true);
 
   // Verify that the pod shows a list of locales beginning with the recommended
   // ones, followed by others.
@@ -1727,6 +1716,7 @@
   const base::DictionaryValue* state = NULL;
   ASSERT_TRUE(value_ptr);
   ASSERT_TRUE(value_ptr->GetAsDictionary(&state));
+  bool advanced = false;
   EXPECT_TRUE(state->GetBoolean("advanced", &advanced));
   EXPECT_TRUE(advanced);
   EXPECT_TRUE(state->GetString("locale", &selected_locale));
@@ -1747,15 +1737,58 @@
 
   // Verify that the locale and keyboard layout have been applied.
   EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
+            icu::Locale::getDefault().getLanguage());
   EXPECT_EQ(public_session_input_method_id_,
             chromeos::input_method::InputMethodManager::Get()->
                 GetCurrentInputMethod().id());
 }
 
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, InvalidRecommendedLocale) {
+  // Specify an invalid recommended locale.
+  SetRecommendedLocales(kInvalidRecommendedLocale,
+                        arraysize(kInvalidRecommendedLocale));
+  UploadAndInstallDeviceLocalAccountPolicy();
+  AddPublicSessionToDevicePolicy(kAccountId1);
+
+  WaitForPolicy();
+
+  // Click on the pod to expand it. Verify that the pod expands to its basic
+  // form as there is only one recommended locale.
+  bool advanced = false;
+  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+      contents_,
+      base::StringPrintf(
+          "var pod ="
+          "    document.getElementById('pod-row').getPodWithUsername_('%s');"
+          "pod.click();"
+          "domAutomationController.send(pod.classList.contains('advanced'));",
+          user_id_1_.c_str()),
+      &advanced));
+  EXPECT_FALSE(advanced);
+  EXPECT_EQ(l10n_util::GetLanguage(initial_locale_),
+            icu::Locale::getDefault().getLanguage());
+
+  // Click the enter button to start the session.
+  ASSERT_TRUE(content::ExecuteScript(
+      contents_,
+      base::StringPrintf(
+          "document.getElementById('pod-row').getPodWithUsername_('%s')"
+          "    .querySelector('.enter-button').click();",
+          user_id_1_.c_str())));
+
+  WaitForSessionStart();
+
+  // Verify that since the recommended locale was invalid, the locale has not
+  // changed and the first keyboard layout applicable to the locale was chosen.
+  EXPECT_EQ(initial_locale_, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(initial_locale_),
+            icu::Locale::getDefault().getLanguage());
+  VerifyKeyboardLayoutMatchesLocale();
+}
+
 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest,
                        AutoLoginWithoutRecommendedLocales) {
-  const std::string initial_locale = g_browser_process->GetApplicationLocale();
-
   UploadAndInstallDeviceLocalAccountPolicy();
   AddPublicSessionToDevicePolicy(kAccountId1);
   EnableAutoLogin();
@@ -1766,7 +1799,8 @@
 
   // Verify that the locale has not changed and the first keyboard layout
   // applicable to the locale was chosen.
-  EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(initial_locale_, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
   VerifyKeyboardLayoutMatchesLocale();
 }
 
@@ -1785,6 +1819,8 @@
   // Verify that the first recommended locale has been applied and the first
   // keyboard layout applicable to the locale was chosen.
   EXPECT_EQ(kRecommendedLocales1[0], g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(kRecommendedLocales1[0]),
+            icu::Locale::getDefault().getLanguage());
   VerifyKeyboardLayoutMatchesLocale();
 }
 
@@ -1872,6 +1908,8 @@
 
   // Verify that the locale and keyboard layout have been applied.
   EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
+            icu::Locale::getDefault().getLanguage());
   EXPECT_EQ(public_session_input_method_id_,
             chromeos::input_method::InputMethodManager::Get()->
                 GetCurrentInputMethod().id());
@@ -1884,6 +1922,8 @@
 
   // Verify that the locale and keyboard layout are still in force.
   EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
+  EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
+            icu::Locale::getDefault().getLanguage());
   EXPECT_EQ(public_session_input_method_id_,
             chromeos::input_method::InputMethodManager::Get()->
                 GetCurrentInputMethod().id());
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
index 5e447e9..a75e7b8 100644
--- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
+++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -207,7 +207,7 @@
 }
 
 void EnrollmentHandlerChromeOS::CheckStateKeys(
-    const std::vector<std::string>& state_keys) {
+    const std::vector<std::string>& state_keys, bool /* first_boot */) {
   CHECK_EQ(STEP_STATE_KEYS, enrollment_step_);
 
   // Make sure state keys are available if forced re-enrollment is on.
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
index 90d6516..275aa2b 100644
--- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
+++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
@@ -121,7 +121,8 @@
   };
 
   // Handles the response to a request for server-backed state keys.
-  void CheckStateKeys(const std::vector<std::string>& state_keys);
+  void CheckStateKeys(const std::vector<std::string>& state_keys,
+                      bool first_boot);
 
   // Starts registration if the store is initialized.
   void AttemptRegistration();
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
index df174e2..99d945d 100644
--- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
@@ -28,6 +28,7 @@
     scoped_refptr<base::TaskRunner> delayed_task_runner)
     : session_manager_client_(session_manager_client),
       delayed_task_runner_(delayed_task_runner),
+      first_boot_(false),
       requested_(false),
       initial_retrieval_completed_(false),
       weak_factory_(this) {
@@ -53,7 +54,7 @@
   }
 
   if (!callback.is_null())
-    callback.Run(state_keys_);
+    callback.Run(state_keys_, first_boot_);
   return;
 }
 
@@ -67,7 +68,7 @@
 }
 
 void ServerBackedStateKeysBroker::StoreStateKeys(
-    const std::vector<std::string>& state_keys) {
+    const std::vector<std::string>& state_keys, bool first_boot) {
   bool send_notification = !initial_retrieval_completed_;
 
   requested_ = false;
@@ -80,6 +81,7 @@
   } else {
     send_notification |= state_keys_ != state_keys;
     state_keys_ = state_keys;
+    first_boot_ = first_boot;
   }
 
   if (send_notification)
@@ -92,7 +94,7 @@
        callback != callbacks.end();
        ++callback) {
     if (!callback->is_null())
-      callback->Run(state_keys_);
+      callback->Run(state_keys_, first_boot_);
   }
 
   delayed_task_runner_->PostDelayedTask(
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
index 3711cad..9f9add4 100644
--- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
@@ -30,7 +30,7 @@
 class ServerBackedStateKeysBroker {
  public:
   typedef scoped_ptr<base::CallbackList<void()>::Subscription> Subscription;
-  typedef base::Callback<void(const std::vector<std::string>&)>
+  typedef base::Callback<void(const std::vector<std::string>&, bool)>
       StateKeysCallback;
 
   ServerBackedStateKeysBroker(
@@ -71,7 +71,8 @@
   void FetchStateKeys();
 
   // Stores newly-received state keys and notifies consumers.
-  void StoreStateKeys(const std::vector<std::string>& state_keys);
+  void StoreStateKeys(const std::vector<std::string>& state_keys,
+                      bool first_boot);
 
   chromeos::SessionManagerClient* session_manager_client_;
 
@@ -80,6 +81,9 @@
   // The current set of state keys.
   std::vector<std::string> state_keys_;
 
+  // Set to true on first run after factory reset.
+  bool first_boot_;
+
   // Whether a request for state keys is pending.
   bool requested_;
 
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
index 2dad66b..32ddf18 100644
--- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
@@ -20,6 +20,7 @@
   ServerBackedStateKeysBrokerTest()
       : task_runner_(new base::TestSimpleTaskRunner()),
         broker_(&fake_session_manager_client_, task_runner_),
+        first_boot_(false),
         updated_(false),
         callback_invoked_(false) {
     state_keys_.push_back("1");
@@ -40,9 +41,11 @@
     EXPECT_EQ(state_keys_.front(), broker_.current_state_key());
   }
 
-  void HandleStateKeysCallback(const std::vector<std::string>& state_keys) {
+  void HandleStateKeysCallback(const std::vector<std::string>& state_keys,
+                               bool first_boot) {
     callback_invoked_ = true;
     callback_state_keys_ = state_keys;
+    first_boot_ = first_boot;
   }
 
  protected:
@@ -51,6 +54,7 @@
   chromeos::FakeSessionManagerClient fake_session_manager_client_;
   ServerBackedStateKeysBroker broker_;
   std::vector<std::string> state_keys_;
+  bool first_boot_;
   bool updated_;
   std::vector<std::string> callback_state_keys_;
   bool callback_invoked_;
@@ -133,6 +137,7 @@
   base::RunLoop().RunUntilIdle();
   ExpectGood();
   EXPECT_TRUE(callback_invoked_);
+  EXPECT_FALSE(first_boot_);
   EXPECT_EQ(state_keys_, callback_state_keys_);
 }
 
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
index 1dc5111..d4b4dd0 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos.cc
@@ -289,6 +289,16 @@
                     new base::StringValue("primary-only"),
                     NULL);
   }
+
+  // Set EasyUnlockAllowed policy to false by default for managed accounts.
+  if (store()->has_policy() &&
+      !policy_map->Get(key::kEasyUnlockAllowed)) {
+    policy_map->Set(key::kEasyUnlockAllowed,
+                    POLICY_LEVEL_MANDATORY,
+                    POLICY_SCOPE_USER,
+                    new base::FundamentalValue(false),
+                    NULL);
+  }
 }
 
 void UserCloudPolicyManagerChromeOS::FetchPolicyOAuthTokenUsingSigninProfile() {
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
index d25d7dc..980c255 100644
--- a/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/user_cloud_policy_manager_chromeos_unittest.cc
@@ -115,6 +115,10 @@
                     POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
                     new base::StringValue("primary-only"),
                     NULL);
+    policy_map_.Set(key::kEasyUnlockAllowed,
+                    POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER,
+                    new base::FundamentalValue(false),
+                    NULL);
     expected_bundle_.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()))
         .CopyFrom(policy_map_);
 
diff --git a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc
index fa3c395..213986f 100644
--- a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc
+++ b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.cc
@@ -12,10 +12,11 @@
 #include "base/memory/weak_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/debug_daemon_client.h"
+#include "components/user_manager/user.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/browser/browser_thread.h"
 
@@ -134,20 +135,24 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   if (succeeded) {
     SystemLogsResponse* response = new SystemLogsResponse;
-    std::vector<Profile*> last_used = ProfileManager::GetLastOpenedProfiles();
 
-    if (last_used.empty() && user_manager::UserManager::IsInitialized() &&
-        user_manager::UserManager::Get()->IsLoggedInAsKioskApp()) {
-      // Use the kiosk app profile explicitly because kiosk session does not
-      // open any browsers thus ProfileManager::GetLastOpenedProfiles returns
-      // an empty |last_used|.
-      last_used.push_back(ProfileManager::GetActiveUserProfile());
+    const user_manager::UserList& users =
+        user_manager::UserManager::Get()->GetLoggedInUsers();
+    std::vector<base::FilePath> profile_dirs;
+    for (user_manager::UserList::const_iterator it = users.begin();
+         it != users.end();
+         ++it) {
+      if ((*it)->username_hash().empty())
+        continue;
+      profile_dirs.push_back(
+          chromeos::ProfileHelper::GetProfilePathByUserIdHash(
+              (*it)->username_hash()));
     }
 
     content::BrowserThread::PostBlockingPoolTaskAndReply(
         FROM_HERE,
         base::Bind(&DebugDaemonLogSource::ReadUserLogFiles,
-                   user_log_files, last_used, response),
+                   user_log_files, profile_dirs, response),
         base::Bind(&DebugDaemonLogSource::MergeResponse,
                    weak_ptr_factory_.GetWeakPtr(),
                    base::Owned(response)));
@@ -160,9 +165,9 @@
 // static
 void DebugDaemonLogSource::ReadUserLogFiles(
     const KeyValueMap& user_log_files,
-    const std::vector<Profile*>& last_used_profiles,
+    const std::vector<base::FilePath>& profile_dirs,
     SystemLogsResponse* response) {
-  for (size_t i = 0; i < last_used_profiles.size(); ++i) {
+  for (size_t i = 0; i < profile_dirs.size(); ++i) {
     std::string profile_prefix = "Profile[" + base::UintToString(i) + "] ";
     for (KeyValueMap::const_iterator it = user_log_files.begin();
          it != user_log_files.end();
@@ -170,9 +175,8 @@
       std::string key = it->first;
       std::string value;
       std::string filename = it->second;
-      base::FilePath profile_dir = last_used_profiles[i]->GetPath();
       bool read_success = base::ReadFileToString(
-          profile_dir.Append(filename), &value);
+          profile_dirs[i].Append(filename), &value);
 
       if (read_success && !value.empty())
         (*response)[profile_prefix + key] = value;
diff --git a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h
index f1c5728..8beb30d 100644
--- a/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h
+++ b/chrome/browser/chromeos/system_logs/debug_daemon_log_source.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/feedback/system_logs/system_logs_fetcher_base.h"
 
@@ -45,7 +46,7 @@
   // the response parameter.
   static void ReadUserLogFiles(
       const KeyValueMap& user_log_files,
-      const std::vector<Profile*>& last_used_profiles,
+      const std::vector<base::FilePath>& profile_dirs,
       SystemLogsResponse* response);
 
   // Merge the responses from ReadUserLogFiles into the main response dict and
diff --git a/chrome/browser/component_updater/widevine_cdm_component_installer.cc b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
index 3d04ec9..663f48e 100644
--- a/chrome/browser/component_updater/widevine_cdm_component_installer.cc
+++ b/chrome/browser/component_updater/widevine_cdm_component_installer.cc
@@ -126,7 +126,9 @@
   plugin_info->is_out_of_process = true;
   plugin_info->path = path;
   plugin_info->name = kWidevineCdmDisplayName;
-  plugin_info->description = kWidevineCdmDescription;
+  plugin_info->description = kWidevineCdmDescription +
+                             std::string(" (version: ") + version.GetString() +
+                             ")";
   plugin_info->version = version.GetString();
   content::WebPluginMimeType widevine_cdm_mime_type(
       kWidevineCdmPluginMimeType,
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket.cc b/chrome/browser/devtools/device/adb/adb_client_socket.cc
index 41b3c9b..0845f92 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket.cc
+++ b/chrome/browser/devtools/device/adb/adb_client_socket.cc
@@ -20,6 +20,9 @@
 const char kHostTransportCommand[] = "host:transport:%s";
 const char kLocalhost[] = "127.0.0.1";
 
+typedef base::Callback<void(int, const std::string&)> CommandCallback;
+typedef base::Callback<void(int, net::StreamSocket*)> SocketCallback;
+
 std::string EncodeMessage(const std::string& message) {
   static const char kHexChars[] = "0123456789ABCDEF";
 
@@ -70,14 +73,14 @@
   void OnSocketAvailable(int result, const std::string& response) {
     if (!CheckNetResultOrDie(result))
       return;
-    callback_.Run(net::OK, socket_.Pass());
+    callback_.Run(net::OK, socket_.release());
     delete this;
   }
 
   bool CheckNetResultOrDie(int result) {
     if (result >= 0)
       return true;
-    callback_.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
+    callback_.Run(result, NULL);
     delete this;
     return false;
   }
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket.h b/chrome/browser/devtools/device/adb/adb_client_socket.h
index f331b02..f0d26ad 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket.h
+++ b/chrome/browser/devtools/device/adb/adb_client_socket.h
@@ -13,7 +13,7 @@
  public:
   typedef base::Callback<void(int, const std::string&)> CommandCallback;
   typedef base::Callback<void(int result,
-                              scoped_ptr<net::StreamSocket>)> SocketCallback;
+                              net::StreamSocket*)> SocketCallback;
 
   static void AdbQuery(int port,
                        const std::string& query,
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
index c35cdeb..9020d60 100644
--- a/chrome/browser/devtools/device/android_device_manager.cc
+++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -50,9 +50,9 @@
     scoped_refptr<base::MessageLoopProxy> response_message_loop,
     const AndroidDeviceManager::SocketCallback& callback,
     int result,
-    scoped_ptr<net::StreamSocket> socket) {
-  response_message_loop->PostTask(
-      FROM_HERE, base::Bind(callback, result, base::Passed(&socket)));
+    net::StreamSocket* socket) {
+  response_message_loop->PostTask(FROM_HERE,
+                                  base::Bind(callback, result, socket));
 }
 
 class HttpRequest {
@@ -61,41 +61,39 @@
   typedef AndroidDeviceManager::SocketCallback SocketCallback;
 
   static void CommandRequest(const std::string& request,
-                             const CommandCallback& callback,
-                             int result,
-                             scoped_ptr<net::StreamSocket> socket) {
+                           const CommandCallback& callback,
+                           int result,
+                           net::StreamSocket* socket) {
     if (result != net::OK) {
       callback.Run(result, std::string());
       return;
     }
-    new HttpRequest(socket.Pass(), request, callback);
+    new HttpRequest(socket, request, callback);
   }
 
   static void SocketRequest(const std::string& request,
-                            const SocketCallback& callback,
-                            int result,
-                            scoped_ptr<net::StreamSocket> socket) {
+                          const SocketCallback& callback,
+                          int result,
+                          net::StreamSocket* socket) {
     if (result != net::OK) {
-      callback.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
+      callback.Run(result, NULL);
       return;
     }
-    new HttpRequest(socket.Pass(), request, callback);
+    new HttpRequest(socket, request, callback);
   }
 
  private:
-  HttpRequest(scoped_ptr<net::StreamSocket> socket,
+  HttpRequest(net::StreamSocket* socket,
               const std::string& request,
               const CommandCallback& callback)
-      : socket_(socket.Pass()),
-        command_callback_(callback),
-        body_pos_(0) {
+      : socket_(socket), command_callback_(callback), body_pos_(0) {
     SendRequest(request);
   }
 
-  HttpRequest(scoped_ptr<net::StreamSocket> socket,
-              const std::string& request,
-              const SocketCallback& callback)
-    : socket_(socket.Pass()),
+  HttpRequest(net::StreamSocket* socket,
+                      const std::string& request,
+                      const SocketCallback& callback)
+    : socket_(socket),
       socket_callback_(callback),
       body_pos_(0) {
     SendRequest(request);
@@ -171,7 +169,7 @@
       if (!command_callback_.is_null())
         command_callback_.Run(net::OK, response_.substr(body_pos_));
       else
-        socket_callback_.Run(net::OK, socket_.Pass());
+        socket_callback_.Run(net::OK, socket_.release());
       delete this;
       return;
     }
@@ -193,7 +191,7 @@
     if (!command_callback_.is_null())
       command_callback_.Run(result, std::string());
     else
-      socket_callback_.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
+      socket_callback_.Run(result, NULL);
     delete this;
     return false;
   }
diff --git a/chrome/browser/devtools/device/android_device_manager.h b/chrome/browser/devtools/device/android_device_manager.h
index fbc00cd..219e5ce 100644
--- a/chrome/browser/devtools/device/android_device_manager.h
+++ b/chrome/browser/devtools/device/android_device_manager.h
@@ -24,8 +24,7 @@
       public base::NonThreadSafe {
  public:
   typedef base::Callback<void(int, const std::string&)> CommandCallback;
-  typedef base::Callback<void(int result, scoped_ptr<net::StreamSocket>)>
-      SocketCallback;
+  typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback;
   typedef base::Callback<void(const std::vector<std::string>&)> SerialsCallback;
 
   struct BrowserInfo {
@@ -54,21 +53,32 @@
 
   typedef base::Callback<void(const DeviceInfo&)> DeviceInfoCallback;
 
-  class AndroidWebSocket {
+  class AndroidWebSocket : public base::RefCountedThreadSafe<AndroidWebSocket> {
    public:
     class Delegate {
      public:
       virtual void OnSocketOpened() = 0;
       virtual void OnFrameRead(const std::string& message) = 0;
-      virtual void OnSocketClosed() = 0;
+      virtual void OnSocketClosed(bool closed_by_device) = 0;
 
      protected:
       virtual ~Delegate() {}
     };
 
+    AndroidWebSocket() {}
+
+    virtual void Connect() = 0;
+    virtual void Disconnect() = 0;
+    virtual void SendFrame(const std::string& message) = 0;
+    virtual void ClearDelegate() = 0;
+
+   protected:
     virtual ~AndroidWebSocket() {}
 
-    virtual void SendFrame(const std::string& message) = 0;
+   private:
+    friend class base::RefCountedThreadSafe<AndroidWebSocket>;
+
+    DISALLOW_COPY_AND_ASSIGN(AndroidWebSocket);
   };
 
   class DeviceProvider;
@@ -93,7 +103,7 @@
                      const std::string& url,
                      const SocketCallback& callback);
 
-    AndroidWebSocket* CreateWebSocket(
+    scoped_refptr<AndroidWebSocket> CreateWebSocket(
         const std::string& socket_name,
         const std::string& url,
         AndroidWebSocket::Delegate* delegate);
diff --git a/chrome/browser/devtools/device/android_web_socket.cc b/chrome/browser/devtools/device/android_web_socket.cc
index a0054da..81d2627 100644
--- a/chrome/browser/devtools/device/android_web_socket.cc
+++ b/chrome/browser/devtools/device/android_web_socket.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
 #include "base/rand_util.h"
 #include "chrome/browser/devtools/device/android_device_manager.h"
@@ -19,127 +18,85 @@
 
 const int kBufferSize = 16 * 1024;
 
-class WebSocketImpl {
- public:
-  typedef AndroidDeviceManager::AndroidWebSocket::Delegate Delegate;
-
-  WebSocketImpl(Delegate* delegate,
-                scoped_ptr<net::StreamSocket> socket);
-  void StartListening();
-  void SendFrame(const std::string& message);
-
- private:
-  void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result);
-  void SendPendingRequests(int result);
-  void Disconnect();
-
-  Delegate* delegate_;
-  scoped_ptr<net::StreamSocket> socket_;
-  std::string response_buffer_;
-  std::string request_buffer_;
-  base::ThreadChecker thread_checker_;
-  DISALLOW_COPY_AND_ASSIGN(WebSocketImpl);
-};
-
-class DelegateWrapper
-    : public AndroidDeviceManager::AndroidWebSocket::Delegate {
- public:
-  DelegateWrapper(base::WeakPtr<Delegate> weak_delegate,
-                  scoped_refptr<base::MessageLoopProxy> message_loop)
-      : weak_delegate_(weak_delegate),
-        message_loop_(message_loop) {
-  }
-
-  virtual ~DelegateWrapper() {}
-
-  // AndroidWebSocket::Delegate implementation
-  virtual void OnSocketOpened() OVERRIDE {
-    message_loop_->PostTask(FROM_HERE,
-        base::Bind(&Delegate::OnSocketOpened, weak_delegate_));
-  }
-
-  virtual void OnFrameRead(const std::string& message) OVERRIDE {
-    message_loop_->PostTask(FROM_HERE,
-        base::Bind(&Delegate::OnFrameRead, weak_delegate_, message));
-  }
-
-  virtual void OnSocketClosed() OVERRIDE {
-    message_loop_->PostTask(FROM_HERE,
-        base::Bind(&Delegate::OnSocketClosed, weak_delegate_));
-  }
-
- private:
-  base::WeakPtr<Delegate> weak_delegate_;
-  scoped_refptr<base::MessageLoopProxy> message_loop_;
-};
-
-class AndroidWebSocketImpl
-    : public AndroidDeviceManager::AndroidWebSocket,
-      public AndroidDeviceManager::AndroidWebSocket::Delegate {
+class WebSocketImpl : public AndroidDeviceManager::AndroidWebSocket {
  public:
   typedef AndroidDeviceManager::Device Device;
-  AndroidWebSocketImpl(
-      scoped_refptr<base::MessageLoopProxy> device_message_loop,
-      scoped_refptr<Device> device,
-      const std::string& socket_name,
-      const std::string& url,
-      AndroidWebSocket::Delegate* delegate);
+  WebSocketImpl(scoped_refptr<base::MessageLoopProxy> device_message_loop,
+                scoped_refptr<Device> device,
+                const std::string& socket_name,
+                const std::string& url,
+                Delegate* delegate);
 
-  virtual ~AndroidWebSocketImpl();
-
-  // AndroidWebSocket implementation
+  virtual void Connect() OVERRIDE;
+  virtual void Disconnect() OVERRIDE;
   virtual void SendFrame(const std::string& message) OVERRIDE;
-
-  // AndroidWebSocket::Delegate implementation
-  virtual void OnSocketOpened() OVERRIDE;
-  virtual void OnFrameRead(const std::string& message) OVERRIDE;
-  virtual void OnSocketClosed() OVERRIDE;
+  virtual void ClearDelegate() OVERRIDE;
 
  private:
-  void Connected(int result, scoped_ptr<net::StreamSocket> socket);
+  friend class base::RefCountedThreadSafe<AndroidWebSocket>;
+
+  virtual ~WebSocketImpl();
+
+  void Connected(int result, net::StreamSocket* socket);
+  void StartListeningOnHandlerThread();
+  void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result);
+  void SendFrameOnHandlerThread(const std::string& message);
+  void SendPendingRequests(int result);
+  void DisconnectOnHandlerThread(bool closed_by_device);
+
+  void OnSocketOpened();
+  void OnFrameRead(const std::string& message);
+  void OnSocketClosed(bool closed_by_device);
 
   scoped_refptr<base::MessageLoopProxy> device_message_loop_;
   scoped_refptr<Device> device_;
   std::string socket_name_;
   std::string url_;
-  WebSocketImpl* connection_;
-  DelegateWrapper* delegate_wrapper_;
-  AndroidWebSocket::Delegate* delegate_;
-  base::WeakPtrFactory<AndroidWebSocketImpl> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(AndroidWebSocketImpl);
+  scoped_ptr<net::StreamSocket> socket_;
+  Delegate* delegate_;
+  std::string response_buffer_;
+  std::string request_buffer_;
 };
 
-AndroidWebSocketImpl::AndroidWebSocketImpl(
+WebSocketImpl::WebSocketImpl(
     scoped_refptr<base::MessageLoopProxy> device_message_loop,
     scoped_refptr<Device> device,
     const std::string& socket_name,
     const std::string& url,
-    AndroidWebSocket::Delegate* delegate)
+    Delegate* delegate)
     : device_message_loop_(device_message_loop),
       device_(device),
       socket_name_(socket_name),
       url_(url),
-      delegate_(delegate),
-      weak_factory_(this) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(delegate_);
-  device_->HttpUpgrade(
-      socket_name_, url_,
-      base::Bind(&AndroidWebSocketImpl::Connected, weak_factory_.GetWeakPtr()));
+      delegate_(delegate) {
 }
 
-void AndroidWebSocketImpl::SendFrame(const std::string& message) {
+void WebSocketImpl::Connect() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  device_->HttpUpgrade(
+      socket_name_, url_, base::Bind(&WebSocketImpl::Connected, this));
+}
+
+void WebSocketImpl::Disconnect() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   device_message_loop_->PostTask(
       FROM_HERE,
-      base::Bind(&WebSocketImpl::SendFrame,
-                 base::Unretained(connection_), message));
+      base::Bind(&WebSocketImpl::DisconnectOnHandlerThread, this, false));
 }
 
 void WebSocketImpl::SendFrame(const std::string& message) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  if (!socket_)
-    return;
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  device_message_loop_->PostTask(
+      FROM_HERE,
+      base::Bind(&WebSocketImpl::SendFrameOnHandlerThread, this, message));
+}
+
+void WebSocketImpl::ClearDelegate() {
+  delegate_ = NULL;
+}
+
+void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) {
+  DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
   int mask = base::RandInt(0, 0x7FFFFFFF);
   std::string encoded_frame = WebSocket::EncodeFrameHybi17(message, mask);
   request_buffer_ += encoded_frame;
@@ -147,55 +104,43 @@
     SendPendingRequests(0);
 }
 
-AndroidWebSocketImpl::~AndroidWebSocketImpl() {
+WebSocketImpl::~WebSocketImpl() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  device_message_loop_->DeleteSoon(FROM_HERE, connection_);
-  device_message_loop_->DeleteSoon(FROM_HERE, delegate_wrapper_);
 }
 
-WebSocketImpl::WebSocketImpl(Delegate* delegate,
-                             scoped_ptr<net::StreamSocket> socket)
-                             : delegate_(delegate),
-                               socket_(socket.Pass()) {
-  thread_checker_.DetachFromThread();
-}
-
-void AndroidWebSocketImpl::Connected(int result,
-                                     scoped_ptr<net::StreamSocket> socket) {
+void WebSocketImpl::Connected(int result, net::StreamSocket* socket) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (result != net::OK || socket == NULL) {
-    OnSocketClosed();
+    OnSocketClosed(true);
     return;
   }
-  delegate_wrapper_ = new DelegateWrapper(weak_factory_.GetWeakPtr(),
-                                          base::MessageLoopProxy::current());
-  connection_ = new WebSocketImpl(delegate_wrapper_, socket.Pass());
+  socket_.reset(socket);
   device_message_loop_->PostTask(
       FROM_HERE,
-      base::Bind(&WebSocketImpl::StartListening,
-                 base::Unretained(connection_)));
+      base::Bind(&WebSocketImpl::StartListeningOnHandlerThread, this));
   OnSocketOpened();
 }
 
-void WebSocketImpl::StartListening() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(socket_);
+void WebSocketImpl::StartListeningOnHandlerThread() {
+  DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
   scoped_refptr<net::IOBuffer> response_buffer =
       new net::IOBuffer(kBufferSize);
   int result = socket_->Read(
       response_buffer.get(),
       kBufferSize,
-      base::Bind(&WebSocketImpl::OnBytesRead,
-                 base::Unretained(this), response_buffer));
+      base::Bind(&WebSocketImpl::OnBytesRead, this, response_buffer));
   if (result != net::ERR_IO_PENDING)
     OnBytesRead(response_buffer, result);
 }
 
-void WebSocketImpl::OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer,
-                                int result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+void WebSocketImpl::OnBytesRead(
+    scoped_refptr<net::IOBuffer> response_buffer, int result) {
+  DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
+  if (!socket_)
+    return;
+
   if (result <= 0) {
-    Disconnect();
+    DisconnectOnHandlerThread(true);
     return;
   }
 
@@ -209,30 +154,32 @@
 
   while (parse_result == WebSocket::FRAME_OK) {
     response_buffer_ = response_buffer_.substr(bytes_consumed);
-    delegate_->OnFrameRead(output);
+    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+        base::Bind(&WebSocketImpl::OnFrameRead, this, output));
     parse_result = WebSocket::DecodeFrameHybi17(
         response_buffer_, false, &bytes_consumed, &output);
   }
 
   if (parse_result == WebSocket::FRAME_ERROR ||
       parse_result == WebSocket::FRAME_CLOSE) {
-    Disconnect();
+    DisconnectOnHandlerThread(true);
     return;
   }
 
   result = socket_->Read(
       response_buffer.get(),
       kBufferSize,
-      base::Bind(&WebSocketImpl::OnBytesRead,
-                 base::Unretained(this), response_buffer));
+      base::Bind(&WebSocketImpl::OnBytesRead, this, response_buffer));
   if (result != net::ERR_IO_PENDING)
     OnBytesRead(response_buffer, result);
 }
 
 void WebSocketImpl::SendPendingRequests(int result) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
+  if (!socket_)
+    return;
   if (result < 0) {
-    Disconnect();
+    DisconnectOnHandlerThread(true);
     return;
   }
   request_buffer_ = request_buffer_.substr(result);
@@ -243,39 +190,43 @@
       new net::StringIOBuffer(request_buffer_);
   result = socket_->Write(buffer.get(), buffer->size(),
                           base::Bind(&WebSocketImpl::SendPendingRequests,
-                                     base::Unretained(this)));
+                                     this));
   if (result != net::ERR_IO_PENDING)
     SendPendingRequests(result);
 }
 
-void WebSocketImpl::Disconnect() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  socket_.reset();
-  delegate_->OnSocketClosed();
+void WebSocketImpl::DisconnectOnHandlerThread(bool closed_by_device) {
+  DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
+  if (!socket_)
+    return;
+  // Wipe out socket_ first since Disconnect can re-enter this method.
+  scoped_ptr<net::StreamSocket> socket(socket_.release());
+  socket->Disconnect();
+  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+      base::Bind(&WebSocketImpl::OnSocketClosed, this, closed_by_device));
 }
 
-void AndroidWebSocketImpl::OnSocketOpened() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  delegate_->OnSocketOpened();
+void WebSocketImpl::OnSocketOpened() {
+  if (delegate_)
+    delegate_->OnSocketOpened();
 }
 
-void AndroidWebSocketImpl::OnFrameRead(const std::string& message) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  delegate_->OnFrameRead(message);
+void WebSocketImpl::OnFrameRead(const std::string& message) {
+  if (delegate_)
+    delegate_->OnFrameRead(message);
 }
 
-void AndroidWebSocketImpl::OnSocketClosed() {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  delegate_->OnSocketClosed();
+void WebSocketImpl::OnSocketClosed(bool closed_by_device) {
+  if (delegate_)
+    delegate_->OnSocketClosed(closed_by_device);
 }
 
 }  // namespace
 
-AndroidDeviceManager::AndroidWebSocket*
+scoped_refptr<AndroidDeviceManager::AndroidWebSocket>
 AndroidDeviceManager::Device::CreateWebSocket(
     const std::string& socket,
     const std::string& url,
     AndroidDeviceManager::AndroidWebSocket::Delegate* delegate) {
-  return new AndroidWebSocketImpl(
-      device_message_loop_, this, socket, url, delegate);
+  return new WebSocketImpl(device_message_loop_, this, socket, url, delegate);
 }
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc
index e58a857..c25c469 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -186,12 +186,11 @@
  private:
   virtual void OnSocketOpened() OVERRIDE;
   virtual void OnFrameRead(const std::string& message) OVERRIDE;
-  virtual void OnSocketClosed() OVERRIDE;
-  virtual ~ProtocolCommand();
+  virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
 
   const std::string command_;
   const base::Closure callback_;
-  scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+  scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
 
   DISALLOW_COPY_AND_ASSIGN(ProtocolCommand);
 };
@@ -202,8 +201,9 @@
     const std::string& command,
     const base::Closure callback)
     : command_(command),
-      callback_(callback),
-      web_socket_(browser->CreateWebSocket(debug_url, this)) {
+      callback_(callback){
+  web_socket_ = browser->CreateWebSocket(debug_url, this);
+  web_socket_->Connect();
 }
 
 void ProtocolCommand::OnSocketOpened() {
@@ -211,16 +211,14 @@
 }
 
 void ProtocolCommand::OnFrameRead(const std::string& message) {
-  delete this;
+  web_socket_->Disconnect();
 }
 
-void ProtocolCommand::OnSocketClosed() {
-  delete this;
-}
-
-ProtocolCommand::~ProtocolCommand() {
-  if (!callback_.is_null())
+void ProtocolCommand::OnSocketClosed(bool closed_by_device) {
+  if (!callback_.is_null()) {
     callback_.Run();
+  }
+  delete this;
 }
 
 }  // namespace
@@ -293,15 +291,14 @@
       const std::string& message) OVERRIDE;
   virtual void OnSocketOpened() OVERRIDE;
   virtual void OnFrameRead(const std::string& message) OVERRIDE;
-  virtual void OnSocketClosed() OVERRIDE;
+  virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
 
   const std::string id_;
-  scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_;
-  const std::string debug_url_;
   bool socket_opened_;
+  bool detached_;
   bool is_web_view_;
   std::vector<std::string> pending_messages_;
-  scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+  scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
   content::DevToolsAgentHost* agent_host_;
   content::DevToolsExternalAgentProxy* proxy_;
   DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
@@ -330,10 +327,10 @@
     scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
     const std::string& debug_url)
     : id_(id),
-      browser_(browser),
-      debug_url_(debug_url),
       socket_opened_(false),
+      detached_(false),
       is_web_view_(browser->IsWebView()),
+      web_socket_(browser->CreateWebSocket(debug_url, this)),
       agent_host_(NULL),
       proxy_(NULL) {
   g_host_delegates.Get()[id] = this;
@@ -341,17 +338,20 @@
 
 AgentHostDelegate::~AgentHostDelegate() {
   g_host_delegates.Get().erase(id_);
+  web_socket_->ClearDelegate();
 }
 
 void AgentHostDelegate::Attach(content::DevToolsExternalAgentProxy* proxy) {
   proxy_ = proxy;
   content::RecordAction(base::UserMetricsAction(is_web_view_ ?
       "DevTools_InspectAndroidWebView" : "DevTools_InspectAndroidPage"));
-  web_socket_.reset(browser_->CreateWebSocket(debug_url_, this));
+  web_socket_->Connect();
 }
 
 void AgentHostDelegate::Detach() {
-  web_socket_.reset();
+  detached_ = true;
+  if (socket_opened_)
+    web_socket_->Disconnect();
 }
 
 void AgentHostDelegate::SendMessageToBackend(const std::string& message) {
@@ -362,6 +362,11 @@
 }
 
 void AgentHostDelegate::OnSocketOpened() {
+  if (detached_) {
+    web_socket_->Disconnect();
+    return;
+  }
+
   socket_opened_ = true;
   for (std::vector<std::string>::iterator it = pending_messages_.begin();
        it != pending_messages_.end(); ++it) {
@@ -375,8 +380,8 @@
       proxy_->DispatchOnClientHost(message);
 }
 
-void AgentHostDelegate::OnSocketClosed() {
-  if (proxy_)
+void AgentHostDelegate::OnSocketClosed(bool closed_by_device) {
+  if (proxy_ && closed_by_device)
     proxy_->ConnectionClosed();
 }
 
@@ -609,7 +614,7 @@
       "adb:" + device_->serial() + ":" + socket_, this, kBrowserTargetSocket);
 }
 
-DevToolsAndroidBridge::AndroidWebSocket*
+scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket>
 DevToolsAndroidBridge::RemoteBrowser::CreateWebSocket(
     const std::string& url,
     DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate) {
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.h b/chrome/browser/devtools/device/devtools_android_bridge.h
index b9cbb76..ddc34bb 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.h
+++ b/chrome/browser/devtools/device/devtools_android_bridge.h
@@ -121,7 +121,7 @@
 
     scoped_refptr<content::DevToolsAgentHost> GetAgentHost();
 
-    AndroidWebSocket* CreateWebSocket(
+    scoped_refptr<AndroidWebSocket> CreateWebSocket(
         const std::string& url,
         DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate);
 
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc
index 35c3652..df610d1 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.cc
+++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -59,11 +59,11 @@
                           int port,
                           const CounterCallback& callback,
                           int result,
-                          scoped_ptr<net::StreamSocket> socket) {
+                          net::StreamSocket* socket) {
     if (result < 0)
       return;
     SocketTunnel* tunnel = new SocketTunnel(callback);
-    tunnel->Start(socket.Pass(), host, port);
+    tunnel->Start(socket, host, port);
   }
 
  private:
@@ -75,9 +75,8 @@
     callback_.Run(1);
   }
 
-  void Start(scoped_ptr<net::StreamSocket> socket,
-             const std::string& host, int port) {
-    remote_socket_.swap(socket);
+  void Start(net::StreamSocket* socket, const std::string& host, int port) {
+    remote_socket_.reset(socket);
 
     host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
     net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port));
@@ -255,13 +254,15 @@
 }  // namespace
 
 class PortForwardingController::Connection
-    : public DevToolsAndroidBridge::AndroidWebSocket::Delegate {
+    : public DevToolsAndroidBridge::AndroidWebSocket::Delegate,
+      public base::RefCountedThreadSafe<
+          Connection,
+          content::BrowserThread::DeleteOnUIThread> {
  public:
   Connection(Registry* registry,
              scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device,
              scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
              const ForwardingMap& forwarding_map);
-  virtual ~Connection();
 
   const PortStatusMap& GetPortStatusMap();
 
@@ -274,6 +275,7 @@
       content::BrowserThread::UI>;
   friend class base::DeleteHelper<Connection>;
 
+  virtual ~Connection();
 
   typedef std::map<int, std::string> ForwardingMap;
 
@@ -290,25 +292,23 @@
   void ProcessBindResponse(int port, PortStatus status);
   void ProcessUnbindResponse(int port, PortStatus status);
 
-  static void UpdateSocketCountOnHandlerThread(
-      base::WeakPtr<Connection> weak_connection, int port, int increment);
+  void UpdateSocketCountOnHandlerThread(int port, int increment);
   void UpdateSocketCount(int port, int increment);
 
   // DevToolsAndroidBridge::AndroidWebSocket::Delegate implementation:
   virtual void OnSocketOpened() OVERRIDE;
   virtual void OnFrameRead(const std::string& message) OVERRIDE;
-  virtual void OnSocketClosed() OVERRIDE;
+  virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
 
   PortForwardingController::Registry* registry_;
   scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device_;
   scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_;
-  scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+  scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
   int command_id_;
   bool connected_;
   ForwardingMap forwarding_map_;
   CommandCallbackMap pending_responses_;
   PortStatusMap port_status_;
-  base::WeakPtrFactory<Connection> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(Connection);
 };
@@ -323,18 +323,27 @@
       browser_(browser),
       command_id_(0),
       connected_(false),
-      forwarding_map_(forwarding_map),
-      weak_factory_(this) {
+      forwarding_map_(forwarding_map) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   (*registry_)[device_->serial()] = this;
-  web_socket_.reset(
-      browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this));
+  web_socket_ = browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this);
+  web_socket_->Connect();
+  AddRef();  // Balanced in OnSocketClosed();
+}
+
+void PortForwardingController::Connection::Shutdown() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  registry_ = NULL;
+  // This will have no effect if the socket is not connected yet.
+  web_socket_->Disconnect();
 }
 
 PortForwardingController::Connection::~Connection() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK(registry_->find(device_->serial()) != registry_->end());
-  registry_->erase(device_->serial());
+  if (registry_) {
+    DCHECK(registry_->find(device_->serial()) != registry_->end());
+    registry_->erase(device_->serial());
+  }
 }
 
 void PortForwardingController::Connection::UpdateForwardingMap(
@@ -431,12 +440,10 @@
     port_status_.erase(it);
 }
 
-// static
 void PortForwardingController::Connection::UpdateSocketCountOnHandlerThread(
-    base::WeakPtr<Connection> weak_connection, int port, int increment) {
+    int port, int increment) {
   BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-     base::Bind(&Connection::UpdateSocketCount,
-                weak_connection, port, increment));
+     base::Bind(&Connection::UpdateSocketCount, this, port, increment));
 }
 
 void PortForwardingController::Connection::UpdateSocketCount(
@@ -460,12 +467,19 @@
 
 void PortForwardingController::Connection::OnSocketOpened() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  if (!registry_) {
+    // Socket was created after Shutdown was called. Disconnect immediately.
+    web_socket_->Disconnect();
+    return;
+  }
   connected_ = true;
   SerializeChanges(kTetheringBind, ForwardingMap(), forwarding_map_);
 }
 
-void PortForwardingController::Connection::OnSocketClosed() {
-  delete this;
+void PortForwardingController::Connection::OnSocketClosed(
+    bool closed_by_device) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  Release();  // Balanced in the constructor.
 }
 
 void PortForwardingController::Connection::OnFrameRead(
@@ -505,8 +519,7 @@
   std::string destination_host = tokens[0];
 
   SocketTunnel::CounterCallback callback =
-      base::Bind(&Connection::UpdateSocketCountOnHandlerThread,
-                 weak_factory_.GetWeakPtr(), port);
+      base::Bind(&Connection::UpdateSocketCountOnHandlerThread, this, port);
 
   device_->OpenSocket(
       connection_id.c_str(),
@@ -593,7 +606,7 @@
     UpdateConnections();
   } else {
     StopListening();
-    STLDeleteValues(&registry_);
+    ShutdownConnections();
     NotifyListeners(DevicesStatus());
   }
 }
@@ -624,6 +637,12 @@
     it->second->UpdateForwardingMap(forwarding_map_);
 }
 
+void PortForwardingController::ShutdownConnections() {
+  for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it)
+    it->second->Shutdown();
+  registry_.clear();
+}
+
 void PortForwardingController::NotifyListeners(
     const DevicesStatus& status) const {
   Listeners copy(listeners_);  // Iterate over copy.
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.h b/chrome/browser/devtools/device/port_forwarding_controller.h
index a904ef5..ae491d7 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.h
+++ b/chrome/browser/devtools/device/port_forwarding_controller.h
@@ -77,6 +77,7 @@
   void StopListening();
 
   void UpdateConnections();
+  void ShutdownConnections();
 
   void NotifyListeners(const DevicesStatus& status) const;
 
diff --git a/chrome/browser/devtools/device/self_device_provider.cc b/chrome/browser/devtools/device/self_device_provider.cc
index f6930b5..ee0f043 100644
--- a/chrome/browser/devtools/device/self_device_provider.cc
+++ b/chrome/browser/devtools/device/self_device_provider.cc
@@ -17,9 +17,9 @@
 
 static void RunSocketCallback(
     const AndroidDeviceManager::SocketCallback& callback,
-    scoped_ptr<net::StreamSocket> socket,
+    net::StreamSocket* socket,
     int result) {
-  callback.Run(result, socket.Pass());
+  callback.Run(result, socket);
 }
 
 }  // namespace
@@ -61,8 +61,7 @@
   base::StringToInt(socket_name, &port);
   net::AddressList address_list =
       net::AddressList::CreateFromIPAddress(ip_number, port);
-  scoped_ptr<net::StreamSocket> socket(new net::TCPClientSocket(
-      address_list, NULL, net::NetLog::Source()));
-  socket->Connect(
-      base::Bind(&RunSocketCallback, callback, base::Passed(&socket)));
+  net::TCPClientSocket* socket = new net::TCPClientSocket(
+      address_list, NULL, net::NetLog::Source());
+  socket->Connect(base::Bind(&RunSocketCallback, callback, socket));
 }
diff --git a/chrome/browser/devtools/device/usb/usb_device_provider.cc b/chrome/browser/devtools/device/usb/usb_device_provider.cc
index 4931499..93c9429 100644
--- a/chrome/browser/devtools/device/usb/usb_device_provider.cc
+++ b/chrome/browser/devtools/device/usb/usb_device_provider.cc
@@ -19,12 +19,9 @@
 const int kBufferSize = 16 * 1024;
 
 void OnOpenSocket(const UsbDeviceProvider::SocketCallback& callback,
-                  net::StreamSocket* socket_raw,
+                  net::StreamSocket* socket,
                   int result) {
-  scoped_ptr<net::StreamSocket> socket(socket_raw);
-  if (result != net::OK)
-    socket.reset();
-  callback.Run(result, socket.Pass());
+  callback.Run(result, result == net::OK ? socket : NULL);
 }
 
 void OnRead(net::StreamSocket* socket,
@@ -71,8 +68,7 @@
     callback.Run(net::ERR_CONNECTION_FAILED, std::string());
     return;
   }
-  int result = socket->Connect(
-      base::Bind(&OpenedForCommand, callback, socket));
+  int result = socket->Connect(base::Bind(&OpenedForCommand, callback, socket));
   if (result != net::ERR_IO_PENDING)
     callback.Run(result, std::string());
 }
@@ -111,21 +107,19 @@
                                    const SocketCallback& callback) {
   UsbDeviceMap::iterator it = device_map_.find(serial);
   if (it == device_map_.end()) {
-    callback.Run(net::ERR_CONNECTION_FAILED,
-                 make_scoped_ptr<net::StreamSocket>(NULL));
+    callback.Run(net::ERR_CONNECTION_FAILED, NULL);
     return;
   }
   std::string socket_name =
       base::StringPrintf(kLocalAbstractCommand, name.c_str());
   net::StreamSocket* socket = it->second->CreateSocket(socket_name);
   if (!socket) {
-    callback.Run(net::ERR_CONNECTION_FAILED,
-                 make_scoped_ptr<net::StreamSocket>(NULL));
+    callback.Run(net::ERR_CONNECTION_FAILED, NULL);
     return;
   }
   int result = socket->Connect(base::Bind(&OnOpenSocket, callback, socket));
   if (result != net::ERR_IO_PENDING)
-    callback.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
+    callback.Run(result, NULL);
 }
 
 void UsbDeviceProvider::ReleaseDevice(const std::string& serial) {
diff --git a/chrome/browser/domain_reliability/service_factory.cc b/chrome/browser/domain_reliability/service_factory.cc
index 0809074..5b4f267 100644
--- a/chrome/browser/domain_reliability/service_factory.cc
+++ b/chrome/browser/domain_reliability/service_factory.cc
@@ -6,7 +6,10 @@
 
 #include "base/command_line.h"
 #include "base/metrics/field_trial.h"
+#include "base/prefs/pref_service.h"
+#include "chrome/browser/browser_process.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/pref_names.h"
 #include "components/domain_reliability/service.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "content/public/browser/browser_context.h"
@@ -56,6 +59,11 @@
   if (!IsDomainReliabilityMonitoringEnabled())
     return NULL;
 
+  if (!g_browser_process->local_state()->GetBoolean(
+          prefs::kMetricsReportingEnabled)) {
+    return NULL;
+  }
+
   return DomainReliabilityService::Create(
       kDomainReliabilityUploadReporterString);
 }
diff --git a/chrome/browser/extensions/api/app_window/app_window_api.cc b/chrome/browser/extensions/api/app_window/app_window_api.cc
index 0f578ac..797596b 100644
--- a/chrome/browser/extensions/api/app_window/app_window_api.cc
+++ b/chrome/browser/extensions/api/app_window/app_window_api.cc
@@ -242,6 +242,9 @@
 
     if (options->alpha_enabled.get()) {
       const char* whitelist[] = {
+#if defined(OS_CHROMEOS)
+        "B58B99751225318C7EB8CF4688B5434661083E07",  // http://crbug.com/410550
+#endif
         "0F42756099D914A026DADFA182871C015735DD95",  // http://crbug.com/323773
         "2D22CDB6583FD0A13758AEBE8B15E45208B4E9A7",
         "E7E2461CE072DF036CF9592740196159E2D7C089",  // http://crbug.com/356200
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc
index eefdbbf..cbd8f83 100644
--- a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.cc
@@ -436,11 +436,13 @@
   results_ = bluetooth_socket::ListenUsingL2cap::Results::Create();
 }
 
-BluetoothSocketConnectFunction::BluetoothSocketConnectFunction() {}
+BluetoothSocketAbstractConnectFunction::
+    BluetoothSocketAbstractConnectFunction() {}
 
-BluetoothSocketConnectFunction::~BluetoothSocketConnectFunction() {}
+BluetoothSocketAbstractConnectFunction::
+    ~BluetoothSocketAbstractConnectFunction() {}
 
-bool BluetoothSocketConnectFunction::Prepare() {
+bool BluetoothSocketAbstractConnectFunction::Prepare() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   params_ = bluetooth_socket::Connect::Params::Create(*args_);
   EXTENSION_FUNCTION_VALIDATE(params_.get());
@@ -449,13 +451,13 @@
   return socket_event_dispatcher_ != NULL;
 }
 
-void BluetoothSocketConnectFunction::AsyncWorkStart() {
+void BluetoothSocketAbstractConnectFunction::AsyncWorkStart() {
   DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
   device::BluetoothAdapterFactory::GetAdapter(
-      base::Bind(&BluetoothSocketConnectFunction::OnGetAdapter, this));
+      base::Bind(&BluetoothSocketAbstractConnectFunction::OnGetAdapter, this));
 }
 
-void BluetoothSocketConnectFunction::OnGetAdapter(
+void BluetoothSocketAbstractConnectFunction::OnGetAdapter(
     scoped_refptr<device::BluetoothAdapter> adapter) {
   DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
   BluetoothApiSocket* socket = GetSocket(params_->socket_id);
@@ -486,13 +488,10 @@
     return;
   }
 
-  device->ConnectToService(
-      uuid,
-      base::Bind(&BluetoothSocketConnectFunction::OnConnect, this),
-      base::Bind(&BluetoothSocketConnectFunction::OnConnectError, this));
+  ConnectToService(device, uuid);
 }
 
-void BluetoothSocketConnectFunction::OnConnect(
+void BluetoothSocketAbstractConnectFunction::OnConnect(
     scoped_refptr<device::BluetoothSocket> socket) {
   DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
 
@@ -516,13 +515,26 @@
   AsyncWorkCompleted();
 }
 
-void BluetoothSocketConnectFunction::OnConnectError(
+void BluetoothSocketAbstractConnectFunction::OnConnectError(
     const std::string& message) {
   DCHECK(BrowserThread::CurrentlyOn(work_thread_id()));
   error_ = message;
   AsyncWorkCompleted();
 }
 
+BluetoothSocketConnectFunction::BluetoothSocketConnectFunction() {}
+
+BluetoothSocketConnectFunction::~BluetoothSocketConnectFunction() {}
+
+void BluetoothSocketConnectFunction::ConnectToService(
+    device::BluetoothDevice* device,
+    const device::BluetoothUUID& uuid) {
+  device->ConnectToService(
+      uuid,
+      base::Bind(&BluetoothSocketConnectFunction::OnConnect, this),
+      base::Bind(&BluetoothSocketConnectFunction::OnConnectError, this));
+}
+
 BluetoothSocketDisconnectFunction::BluetoothSocketDisconnectFunction() {}
 
 BluetoothSocketDisconnectFunction::~BluetoothSocketDisconnectFunction() {}
diff --git a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h
index 9ed7406..34da64b 100644
--- a/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h
+++ b/chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h
@@ -208,7 +208,35 @@
   scoped_ptr<bluetooth_socket::ListenUsingL2cap::Params> params_;
 };
 
-class BluetoothSocketConnectFunction : public BluetoothSocketAsyncApiFunction {
+class BluetoothSocketAbstractConnectFunction :
+    public BluetoothSocketAsyncApiFunction {
+ public:
+  BluetoothSocketAbstractConnectFunction();
+
+ protected:
+  virtual ~BluetoothSocketAbstractConnectFunction();
+
+  // BluetoothSocketAsyncApiFunction:
+  virtual bool Prepare() OVERRIDE;
+  virtual void AsyncWorkStart() OVERRIDE;
+
+  // Subclasses should implement this method to connect to the service
+  // registered with |uuid| on the |device|.
+  virtual void ConnectToService(device::BluetoothDevice* device,
+                                const device::BluetoothUUID& uuid) = 0;
+
+  virtual void OnConnect(scoped_refptr<device::BluetoothSocket> socket);
+  virtual void OnConnectError(const std::string& message);
+
+ private:
+  virtual void OnGetAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
+
+  scoped_ptr<bluetooth_socket::Connect::Params> params_;
+  BluetoothSocketEventDispatcher* socket_event_dispatcher_;
+};
+
+class BluetoothSocketConnectFunction :
+    public BluetoothSocketAbstractConnectFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("bluetoothSocket.connect",
                              BLUETOOTHSOCKET_CONNECT);
@@ -218,17 +246,9 @@
  protected:
   virtual ~BluetoothSocketConnectFunction();
 
-  // BluetoothSocketAsyncApiFunction:
-  virtual bool Prepare() OVERRIDE;
-  virtual void AsyncWorkStart() OVERRIDE;
-
- private:
-  virtual void OnGetAdapter(scoped_refptr<device::BluetoothAdapter> adapter);
-  virtual void OnConnect(scoped_refptr<device::BluetoothSocket> socket);
-  virtual void OnConnectError(const std::string& message);
-
-  scoped_ptr<bluetooth_socket::Connect::Params> params_;
-  BluetoothSocketEventDispatcher* socket_event_dispatcher_;
+  // BluetoothSocketAbstractConnectFunction:
+  virtual void ConnectToService(device::BluetoothDevice* device,
+                                const device::BluetoothUUID& uuid) OVERRIDE;
 };
 
 class BluetoothSocketDisconnectFunction
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
index 2c242b1..2864688 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -60,6 +60,8 @@
       return EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE;
     case easy_unlock_private::STATE_PHONE_NOT_NEARBY:
       return EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY;
+    case easy_unlock_private::STATE_PHONE_UNSUPPORTED:
+      return EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED;
     case easy_unlock_private::STATE_AUTHENTICATED:
       return EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED;
     default:
@@ -401,6 +403,26 @@
   }
 }
 
+EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
+    EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
+
+EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
+    ~EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction() {}
+
+void EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
+    ConnectToService(device::BluetoothDevice* device,
+                     const device::BluetoothUUID& uuid) {
+  easy_unlock::ConnectToBluetoothServiceInsecurely(
+      device,
+      uuid,
+      base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
+                     OnConnect,
+                 this),
+      base::Bind(&EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction::
+                     OnConnectError,
+                 this));
+}
+
 EasyUnlockPrivateUpdateScreenlockStateFunction::
     EasyUnlockPrivateUpdateScreenlockStateFunction() {}
 
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
index 215b469..e325ff6 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.h
@@ -9,6 +9,7 @@
 
 #include "base/basictypes.h"
 #include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/api/bluetooth_socket/bluetooth_socket_api.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
 #include "extensions/browser/extension_function.h"
 
@@ -164,6 +165,25 @@
       EasyUnlockPrivateSeekBluetoothDeviceByAddressFunction);
 };
 
+class EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction
+    : public BluetoothSocketAbstractConnectFunction {
+ public:
+  DECLARE_EXTENSION_FUNCTION(
+      "easyUnlockPrivate.connectToBluetoothServiceInsecurely",
+      EASYUNLOCKPRIVATE_CONNECTTOBLUETOOTHSERVICEINSECURELY)
+  EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction();
+
+ private:
+  virtual ~EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction();
+
+  // BluetoothSocketAbstractConnectFunction:
+  virtual void ConnectToService(device::BluetoothDevice* device,
+                                const device::BluetoothUUID& uuid) OVERRIDE;
+
+  DISALLOW_COPY_AND_ASSIGN(
+      EasyUnlockPrivateConnectToBluetoothServiceInsecurelyFunction);
+};
+
 class EasyUnlockPrivateUpdateScreenlockStateFunction
     : public SyncExtensionFunction {
  public:
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.cc
index 2881152..a8ee859 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.cc
@@ -6,6 +6,8 @@
 
 #include "base/callback.h"
 
+using device::BluetoothDevice;
+
 namespace extensions {
 namespace api {
 namespace easy_unlock {
@@ -24,6 +26,14 @@
   result.error_message = kApiUnavailable;
   callback.Run(result);
 }
+
+void ConnectToBluetoothServiceInsecurely(
+    device::BluetoothDevice* device,
+    const device::BluetoothUUID& uuid,
+    const BluetoothDevice::ConnectToServiceCallback& callback,
+    const BluetoothDevice::ConnectToServiceErrorCallback& error_callback) {
+  error_callback.Run(kApiUnavailable);
+}
 #endif  // !defined(OS_CHROMEOS)
 
 }  // namespace easy_unlock
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.h b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.h
index 7679ad4..10a0c28 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.h
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util.h
@@ -8,6 +8,11 @@
 #include <string>
 
 #include "base/callback_forward.h"
+#include "device/bluetooth/bluetooth_device.h"
+
+namespace device {
+class BluetoothUUID;
+}
 
 namespace extensions {
 namespace api {
@@ -28,6 +33,13 @@
 void SeekBluetoothDeviceByAddress(const std::string& device_address,
                                   const SeekDeviceCallback& callback);
 
+void ConnectToBluetoothServiceInsecurely(
+    device::BluetoothDevice* device,
+    const device::BluetoothUUID& uuid,
+    const device::BluetoothDevice::ConnectToServiceCallback& callback,
+    const device::BluetoothDevice::ConnectToServiceErrorCallback&
+        error_callback);
+
 }  // namespace easy_unlock
 }  // namespace api
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util_chromeos.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util_chromeos.cc
index e83e9b7..80a8d2b 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util_chromeos.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_bluetooth_util_chromeos.cc
@@ -22,6 +22,7 @@
 #include "base/time/time.h"
 #include "content/public/browser/browser_thread.h"
 #include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_device_chromeos.h"
 #include "net/socket/socket_descriptor.h"
 
 namespace extensions {
@@ -119,6 +120,15 @@
       callback);
 }
 
+void ConnectToBluetoothServiceInsecurely(
+    device::BluetoothDevice* device,
+    const device::BluetoothUUID& uuid,
+    const BluetoothDevice::ConnectToServiceCallback& callback,
+    const BluetoothDevice::ConnectToServiceErrorCallback& error_callback) {
+  static_cast<chromeos::BluetoothDeviceChromeOS*>(device)
+      ->ConnectToServiceInsecurely(uuid, callback, error_callback);
+}
+
 }  // namespace easy_unlock
 }  // namespace api
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_crypto_delegate_chromeos.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_crypto_delegate_chromeos.cc
index 5a18d9e..f5b0d11 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_crypto_delegate_chromeos.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_crypto_delegate_chromeos.cc
@@ -93,7 +93,7 @@
   }
 
  private:
-  scoped_ptr<chromeos::EasyUnlockClient> dbus_client_;
+  chromeos::EasyUnlockClient* dbus_client_;
 
   DISALLOW_COPY_AND_ASSIGN(EasyUnlockPrivateCryptoDelegateChromeOS);
 };
diff --git a/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc b/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc
index eb7b6e2..f5e44b2 100644
--- a/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc
+++ b/chrome/browser/extensions/api/screenlock_private/screenlock_private_api.cc
@@ -57,6 +57,8 @@
       // locking.
       NOTREACHED();
       return screenlock::AUTH_TYPE_NONE;
+    case ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD:
+      return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
   }
   NOTREACHED();
   return screenlock::AUTH_TYPE_OFFLINEPASSWORD;
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
index 9e6b95c..a25e02d 100644
--- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
+++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -29,6 +29,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
 #include "extensions/browser/extension_host.h"
 #include "extensions/browser/extension_message_filter.h"
 #include "extensions/browser/extension_registry.h"
@@ -564,8 +565,12 @@
   if (!process)
     return;
   DCHECK(profile);
-  if (ProcessMap::Get(profile)->Contains(process->GetID()))
+  if (ProcessMap::Get(profile)->Contains(process->GetID())) {
     command_line->AppendSwitch(switches::kExtensionProcess);
+#if defined(ENABLE_WEBRTC)
+    command_line->AppendSwitch(::switches::kEnableWebRtcHWH264Encoding);
+#endif
+  }
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
index 82bf26c..947068f 100644
--- a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
+++ b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
@@ -207,6 +207,7 @@
 class MTPDeviceDelegateImplLinux::MTPFileNode {
  public:
   MTPFileNode(uint32 file_id,
+              const std::string& file_name,
               MTPFileNode* parent,
               FileIdToMTPFileNodeMap* file_id_to_node_map);
   ~MTPFileNode();
@@ -222,6 +223,7 @@
   bool DeleteChild(uint32 file_id);
 
   uint32 file_id() const { return file_id_; }
+  const std::string& file_name() const { return file_name_; }
   MTPFileNode* parent() { return parent_; }
 
  private:
@@ -229,6 +231,8 @@
   typedef base::ScopedPtrHashMap<std::string, MTPFileNode> ChildNodes;
 
   const uint32 file_id_;
+  const std::string file_name_;
+
   ChildNodes children_;
   MTPFileNode* const parent_;
   FileIdToMTPFileNodeMap* file_id_to_node_map_;
@@ -238,9 +242,11 @@
 
 MTPDeviceDelegateImplLinux::MTPFileNode::MTPFileNode(
     uint32 file_id,
+    const std::string& file_name,
     MTPFileNode* parent,
     FileIdToMTPFileNodeMap* file_id_to_node_map)
     : file_id_(file_id),
+      file_name_(file_name),
       parent_(parent),
       file_id_to_node_map_(file_id_to_node_map) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -272,7 +278,7 @@
 
   children_.set(
       name,
-      make_scoped_ptr(new MTPFileNode(id, this, file_id_to_node_map_)));
+      make_scoped_ptr(new MTPFileNode(id, name, this, file_id_to_node_map_)));
 }
 
 void MTPDeviceDelegateImplLinux::MTPFileNode::ClearNonexistentChildren(
@@ -309,7 +315,8 @@
       task_in_progress_(false),
       device_path_(device_location),
       root_node_(new MTPFileNode(mtpd::kRootFileId,
-                                 NULL,
+                                 "",    // Root node has no name.
+                                 NULL,  // And no parent node.
                                  &file_id_to_node_map_)),
       weak_ptr_factory_(this) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
@@ -328,6 +335,24 @@
     const ErrorCallback& error_callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
   DCHECK(!file_path.empty());
+
+  // If a ReadDirectory operation is in progress, the file info may already be
+  // cached.
+  FileInfoCache::const_iterator it = file_info_cache_.find(file_path);
+  if (it != file_info_cache_.end()) {
+    // TODO(thestig): This code is repeated in several places. Combine them.
+    // e.g. c/b/media_galleries/win/mtp_device_operations_util.cc
+    const fileapi::DirectoryEntry& cached_file_entry = it->second;
+    base::File::Info info;
+    info.size = cached_file_entry.size;
+    info.is_directory = cached_file_entry.is_directory;
+    info.is_symbolic_link = false;
+    info.last_modified = cached_file_entry.last_modified_time;
+    info.creation_time = base::Time();
+
+    success_callback.Run(info);
+    return;
+  }
   base::Closure closure =
       base::Bind(&MTPDeviceDelegateImplLinux::GetFileInfoInternal,
                  weak_ptr_factory_.GetWeakPtr(),
@@ -733,6 +758,17 @@
   DCHECK(it != file_id_to_node_map_.end());
   MTPFileNode* dir_node = it->second;
 
+  // Traverse the MTPFileNode tree to reconstuct the full path for |dir_id|.
+  std::deque<std::string> dir_path_parts;
+  MTPFileNode* parent_node = dir_node;
+  while (parent_node->parent()) {
+    dir_path_parts.push_front(parent_node->file_name());
+    parent_node = parent_node->parent();
+  }
+  base::FilePath dir_path = device_path_;
+  for (size_t i = 0; i < dir_path_parts.size(); ++i)
+    dir_path = dir_path.Append(dir_path_parts[i]);
+
   fileapi::AsyncFileUtil::EntryList normalized_file_list;
   for (size_t i = 0; i < file_list.size(); ++i) {
     normalized_file_list.push_back(file_list[i]);
@@ -751,6 +787,9 @@
     // Refresh the in memory tree.
     dir_node->EnsureChildExists(entry.name, file_id);
     child_nodes_seen_.insert(entry.name);
+
+    // Add to |file_info_cache_|.
+    file_info_cache_[dir_path.Append(entry.name)] = entry;
   }
 
   success_callback.Run(normalized_file_list, has_more);
@@ -760,6 +799,7 @@
   // Last call, finish book keeping and continue with the next request.
   dir_node->ClearNonexistentChildren(child_nodes_seen_);
   child_nodes_seen_.clear();
+  file_info_cache_.clear();
 
   PendingRequestDone();
 }
diff --git a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h
index 44d390d..770c060 100644
--- a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h
+++ b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.h
@@ -60,6 +60,9 @@
   // Maps file ids to file nodes.
   typedef std::map<uint32, MTPFileNode*> FileIdToMTPFileNodeMap;
 
+  // Maps file paths to file info.
+  typedef std::map<base::FilePath, fileapi::DirectoryEntry> FileInfoCache;
+
   // Should only be called by CreateMTPDeviceAsyncDelegate() factory call.
   // Defer the device initializations until the first file operation request.
   // Do all the initializations in EnsureInitAndRunTask() function.
@@ -278,6 +281,11 @@
   // can return results over multiple callbacks, is in progress.
   std::set<std::string> child_nodes_seen_;
 
+  // A cache to store file metadata for file entries read during a ReadDirectory
+  // operation. Used to service incoming GetFileInfo calls for the duration of
+  // the ReadDirectory operation.
+  FileInfoCache file_info_cache_;
+
   // For callbacks that may run after destruction.
   base::WeakPtrFactory<MTPDeviceDelegateImplLinux> weak_ptr_factory_;
 
diff --git a/chrome/browser/net/prediction_options.cc b/chrome/browser/net/prediction_options.cc
index a01f5ee..f525388 100644
--- a/chrome/browser/net/prediction_options.cc
+++ b/chrome/browser/net/prediction_options.cc
@@ -12,56 +12,38 @@
 #include "content/public/browser/browser_thread.h"
 #include "net/base/network_change_notifier.h"
 
+namespace chrome_browser_net {
+
 namespace {
 
 // Since looking up preferences and current network connection are presumably
 // both cheap, we do not cache them here.
-bool CanPrefetchAndPrerender(int network_prediction_options,
-                             bool network_prediction_enabled) {
+bool CanPrefetchAndPrerender(int network_prediction_options) {
   switch (network_prediction_options) {
-    case chrome_browser_net::NETWORK_PREDICTION_ALWAYS:
+    case NETWORK_PREDICTION_ALWAYS:
       return true;
-    case chrome_browser_net::NETWORK_PREDICTION_WIFI_ONLY:
-      return !net::NetworkChangeNotifier::IsConnectionCellular(
-          net::NetworkChangeNotifier::GetConnectionType());
-    case chrome_browser_net::NETWORK_PREDICTION_NEVER:
+    case NETWORK_PREDICTION_NEVER:
       return false;
-    case chrome_browser_net::NETWORK_PREDICTION_UNSET:
-      return network_prediction_enabled;
     default:
-      NOTREACHED() << "Unknown kNetworkPredictionOptions value.";
-      return false;
+      DCHECK_EQ(NETWORK_PREDICTION_WIFI_ONLY, network_prediction_options);
+      return !net::NetworkChangeNotifier::IsConnectionCellular(
+                 net::NetworkChangeNotifier::GetConnectionType());
   }
 }
 
-bool CanPreresolveAndPreconnect(int network_prediction_options,
-                                bool network_prediction_enabled) {
-  switch (network_prediction_options) {
-    case chrome_browser_net::NETWORK_PREDICTION_ALWAYS:
-      return true;
-    // DNS preresolution and TCP preconnect are performed even on cellular
-    // networks if the user setting is WIFI_ONLY.
-    case chrome_browser_net::NETWORK_PREDICTION_WIFI_ONLY:
-      return true;
-    case chrome_browser_net::NETWORK_PREDICTION_NEVER:
-      return false;
-    case chrome_browser_net::NETWORK_PREDICTION_UNSET:
-      return network_prediction_enabled;
-    default:
-      NOTREACHED() << "Unknown kNetworkPredictionOptions value.";
-      return false;
-  }
+bool CanPreresolveAndPreconnect(int network_prediction_options) {
+  // DNS preresolution and TCP preconnect are performed even on cellular
+  // networks if the user setting is WIFI_ONLY.
+  return network_prediction_options != NETWORK_PREDICTION_NEVER;
 }
 
 }  // namespace
 
-namespace chrome_browser_net {
-
 void RegisterPredictionOptionsProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
   registry->RegisterIntegerPref(
       prefs::kNetworkPredictionOptions,
-      chrome_browser_net::NETWORK_PREDICTION_UNSET,
+      NETWORK_PREDICTION_DEFAULT,
       user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 }
 
@@ -81,8 +63,7 @@
   if (network_prediction_enabled->GetAsBoolean(&value)) {
     pref_service->SetInteger(
         prefs::kNetworkPredictionOptions,
-        value ? chrome_browser_net::NETWORK_PREDICTION_WIFI_ONLY
-              : chrome_browser_net::NETWORK_PREDICTION_NEVER);
+        value ? NETWORK_PREDICTION_WIFI_ONLY : NETWORK_PREDICTION_NEVER);
   }
 }
 
@@ -90,16 +71,14 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   DCHECK(profile_io_data);
   return CanPrefetchAndPrerender(
-      profile_io_data->network_prediction_options()->GetValue(),
-      profile_io_data->network_prediction_enabled()->GetValue());
+      profile_io_data->network_prediction_options()->GetValue());
 }
 
 bool CanPrefetchAndPrerenderUI(PrefService* prefs) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   DCHECK(prefs);
   return CanPrefetchAndPrerender(
-      prefs->GetInteger(prefs::kNetworkPredictionOptions),
-      prefs->GetBoolean(prefs::kNetworkPredictionEnabled));
+      prefs->GetInteger(prefs::kNetworkPredictionOptions));
 }
 
 bool CanPredictNetworkActionsUI(PrefService* prefs) {
@@ -110,16 +89,14 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
   DCHECK(profile_io_data);
   return CanPreresolveAndPreconnect(
-      profile_io_data->network_prediction_options()->GetValue(),
-      profile_io_data->network_prediction_enabled()->GetValue());
+      profile_io_data->network_prediction_options()->GetValue());
 }
 
 bool CanPreresolveAndPreconnectUI(PrefService* prefs) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   DCHECK(prefs);
   return CanPreresolveAndPreconnect(
-      prefs->GetInteger(prefs::kNetworkPredictionOptions),
-      prefs->GetBoolean(prefs::kNetworkPredictionEnabled));
+      prefs->GetInteger(prefs::kNetworkPredictionOptions));
 }
 
 }  // namespace chrome_browser_net
diff --git a/chrome/browser/net/prediction_options.h b/chrome/browser/net/prediction_options.h
index 49c33df..1fec4cc 100644
--- a/chrome/browser/net/prediction_options.h
+++ b/chrome/browser/net/prediction_options.h
@@ -17,14 +17,11 @@
 // Enum describing when to allow network predictions based on connection type.
 // The numerical value is stored in the prefs file, therefore the same enum
 // with the same order must be used by the platform-dependent components.
-// TODO(bnc): implement as per crbug.com/334602.
-// NETWORK_PREDICTION_UNSET means that the old preferences,
-// kNetworkPredictionEnabled and kAllowPrerender, should be observed.
 enum NetworkPredictionOptions {
   NETWORK_PREDICTION_ALWAYS,
   NETWORK_PREDICTION_WIFI_ONLY,
   NETWORK_PREDICTION_NEVER,
-  NETWORK_PREDICTION_UNSET,
+  NETWORK_PREDICTION_DEFAULT = NETWORK_PREDICTION_WIFI_ONLY,
 };
 
 void RegisterPredictionOptionsProfilePrefs(
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index c5c50bf..4a8b5d3 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -92,9 +92,6 @@
 
 bool ChromePasswordManagerClient::IsPasswordManagerEnabledForCurrentPage()
     const {
-  if (EnabledForSyncSignin())
-    return true;
-
   DCHECK(web_contents());
   content::NavigationEntry* entry =
       web_contents()->GetController().GetLastCommittedEntry();
@@ -102,6 +99,14 @@
     // TODO(gcasto): Determine if fix for crbug.com/388246 is relevant here.
     return true;
   }
+
+  // Disable the password manager for online password management.
+  if (IsURLPasswordWebsiteReauth(entry->GetURL()))
+    return false;
+
+  if (EnabledForSyncSignin())
+    return true;
+
   // Do not fill nor save password when a user is signing in for sync. This
   // is because users need to remember their password if they are syncing as
   // this is effectively their master password.
@@ -403,6 +408,26 @@
                                     &ignored_value);
 }
 
+bool ChromePasswordManagerClient::IsURLPasswordWebsiteReauth(
+    const GURL& url) const {
+  if (url.GetOrigin() != GaiaUrls::GetInstance()->gaia_url().GetOrigin())
+    return false;
+
+  // "rart" param signals this page is for transactional reauth.
+  std::string param_value;
+  if (!net::GetValueForKeyInQuery(url, "rart", &param_value))
+    return false;
+
+  // Check the "continue" param to see if this reauth page is for the passwords
+  // website.
+  param_value.clear();
+  if (!net::GetValueForKeyInQuery(url, "continue", &param_value))
+    return false;
+
+  return GURL(param_value).host() ==
+      GURL(chrome::kPasswordManagerAccountDashboardURL).host();
+}
+
 bool ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled() {
 #if !defined(USE_AURA)
   return false;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index 4fbed64..ccab0ed 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -138,6 +138,10 @@
   // Google property.
   bool LastLoadWasTransactionalReauthPage() const;
 
+  // Returns true if |url| is the reauth page for accessing the password
+  // website.
+  bool IsURLPasswordWebsiteReauth(const GURL& url) const;
+
   // Sets |autofill_state_| based on experiment and flag values.
   void SetUpAutofillSyncState();
 
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 802bdce..157aaee 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -266,3 +266,58 @@
   NavigateAndCommit(GURL("https://accounts.google.com/Login"));
   EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
 }
+
+TEST_F(ChromePasswordManagerClientTest,
+       IsPasswordManagerEnabledForCurrentPage) {
+  ChromePasswordManagerClient* client = GetClient();
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "https://passwords.google.com/settings&rart=123"));
+  EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Password site is inaccesible via HTTP, but because of HSTS the following
+  // link should still continue to https://passwords.google.com.
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "http://passwords.google.com/settings&rart=123"));
+  EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Specifying default port still passes.
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "https://passwords.google.com:443/settings&rart=123"));
+  EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Encoded URL is considered the same.
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "https://passwords.%67oogle.com/settings&rart=123"));
+  EXPECT_FALSE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Fully qualified domain name is considered a different hostname by GURL.
+  // Ideally this would not be the case, but this quirk can be avoided by
+  // verification on the server. This test is simply documentation of this
+  // behavior.
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "https://passwords.google.com./settings&rart=123"));
+  EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Not a transactional reauth page.
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "https://passwords.google.com/settings"));
+  EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Should be enabled for other transactional reauth pages.
+  NavigateAndCommit(
+      GURL("https://accounts.google.com/ServiceLogin?continue="
+           "https://mail.google.com&rart=234"));
+  EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
+
+  // Reauth pages are only on accounts.google.com
+  NavigateAndCommit(
+      GURL("https://other.site.com/ServiceLogin?continue="
+           "https://passwords.google.com&rart=234"));
+  EXPECT_TRUE(client->IsPasswordManagerEnabledForCurrentPage());
+}
diff --git a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
index 238fdd1..0d854e4 100644
--- a/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
+++ b/chrome/browser/policy/cloud/cloud_policy_browsertest.cc
@@ -142,6 +142,11 @@
                   POLICY_SCOPE_USER,
                   new base::StringValue("primary-only"),
                   NULL);
+  policy_map->Set(key::kEasyUnlockAllowed,
+                  POLICY_LEVEL_MANDATORY,
+                  POLICY_SCOPE_USER,
+                  new base::FundamentalValue(false),
+                  NULL);
 #endif
 }
 
@@ -178,6 +183,11 @@
                 POLICY_SCOPE_USER,
                 new base::StringValue("primary-only"),
                 NULL);
+  expected->Set(key::kEasyUnlockAllowed,
+                POLICY_LEVEL_MANDATORY,
+                POLICY_SCOPE_USER,
+                new base::FundamentalValue(false),
+                NULL);
 #endif
 }
 
diff --git a/chrome/browser/prefetch/prefetch.cc b/chrome/browser/prefetch/prefetch.cc
index c38147f..4b23f86 100644
--- a/chrome/browser/prefetch/prefetch.cc
+++ b/chrome/browser/prefetch/prefetch.cc
@@ -19,17 +19,6 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
 
   ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context);
-  DCHECK(io_data);
-
-  // TODO(bnc): Remove this condition once the new
-  // predictive preference is used on all platforms. See crbug.com/334602.
-  if (io_data->network_prediction_options()->GetValue() ==
-          chrome_browser_net::NETWORK_PREDICTION_UNSET &&
-      net::NetworkChangeNotifier::IsConnectionCellular(
-          net::NetworkChangeNotifier::GetConnectionType())) {
-    return false;
-  }
-
   return chrome_browser_net::CanPrefetchAndPrerenderIO(io_data) &&
          !DisableForFieldTrial();
 }
diff --git a/chrome/browser/prefetch/prefetch_browsertest.cc b/chrome/browser/prefetch/prefetch_browsertest.cc
index bd8ba5b..0f371fc 100644
--- a/chrome/browser/prefetch/prefetch_browsertest.cc
+++ b/chrome/browser/prefetch/prefetch_browsertest.cc
@@ -6,6 +6,7 @@
 #include "base/prefs/pref_service.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -17,39 +18,50 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
+#include "net/base/network_change_notifier.h"
 #include "net/url_request/url_request_filter.h"
 #include "net/url_request/url_request_job.h"
 
+using chrome_browser_net::NetworkPredictionOptions;
 using content::BrowserThread;
+using net::NetworkChangeNotifier;
 
 namespace {
 
 const char kPrefetchPage[] = "files/prerender/simple_prefetch.html";
 
+class MockNetworkChangeNotifierWIFI : public NetworkChangeNotifier {
+ public:
+  virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
+    return NetworkChangeNotifier::CONNECTION_WIFI;
+  }
+};
+
+class MockNetworkChangeNotifier4G : public NetworkChangeNotifier {
+ public:
+  virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
+    return NetworkChangeNotifier::CONNECTION_4G;
+  }
+};
+
 class PrefetchBrowserTestBase : public InProcessBrowserTest {
  public:
-  explicit PrefetchBrowserTestBase(bool do_predictive_networking,
-                                   bool do_prefetch_field_trial)
-      : do_predictive_networking_(do_predictive_networking),
-        do_prefetch_field_trial_(do_prefetch_field_trial) {}
+  explicit PrefetchBrowserTestBase(bool disabled_via_field_trial)
+      : disabled_via_field_trial_(disabled_via_field_trial) {}
 
   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
-    if (do_prefetch_field_trial_) {
+    if (disabled_via_field_trial_) {
       command_line->AppendSwitchASCII(switches::kForceFieldTrials,
                                       "Prefetch/ExperimentDisabled/");
-    } else {
-      command_line->AppendSwitchASCII(switches::kForceFieldTrials,
-                                      "Prefetch/ExperimentEnabled/");
     }
   }
 
-  virtual void SetUpOnMainThread() OVERRIDE {
-    browser()->profile()->GetPrefs()->SetBoolean(
-        prefs::kNetworkPredictionEnabled, do_predictive_networking_);
+  void SetPreference(NetworkPredictionOptions value) {
+    browser()->profile()->GetPrefs()->SetInteger(
+        prefs::kNetworkPredictionOptions, value);
   }
 
   bool RunPrefetchExperiment(bool expect_success, Browser* browser) {
-    CHECK(test_server()->Start());
     GURL url = test_server()->GetURL(kPrefetchPage);
 
     const base::string16 expected_title =
@@ -62,32 +74,17 @@
   }
 
  private:
-  bool do_predictive_networking_;
-  bool do_prefetch_field_trial_;
+  bool disabled_via_field_trial_;
 };
 
-class PrefetchBrowserTestPredictionOnExpOn : public PrefetchBrowserTestBase {
+class PrefetchBrowserTestPrediction : public PrefetchBrowserTestBase {
  public:
-  PrefetchBrowserTestPredictionOnExpOn()
-      : PrefetchBrowserTestBase(true, true) {}
+  PrefetchBrowserTestPrediction() : PrefetchBrowserTestBase(false) {}
 };
 
-class PrefetchBrowserTestPredictionOnExpOff : public PrefetchBrowserTestBase {
+class PrefetchBrowserTestPredictionDisabled : public PrefetchBrowserTestBase {
  public:
-  PrefetchBrowserTestPredictionOnExpOff()
-      : PrefetchBrowserTestBase(true, false) {}
-};
-
-class PrefetchBrowserTestPredictionOffExpOn : public PrefetchBrowserTestBase {
- public:
-  PrefetchBrowserTestPredictionOffExpOn()
-      : PrefetchBrowserTestBase(false, true) {}
-};
-
-class PrefetchBrowserTestPredictionOffExpOff : public PrefetchBrowserTestBase {
- public:
-  PrefetchBrowserTestPredictionOffExpOff()
-      : PrefetchBrowserTestBase(false, false) {}
+  PrefetchBrowserTestPredictionDisabled() : PrefetchBrowserTestBase(true) {}
 };
 
 // URLRequestJob (and associated handler) which hangs.
@@ -134,29 +131,59 @@
       url, never_respond_handler.Pass());
 }
 
-// Privacy option is on, experiment is on.  Prefetch should succeed.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOn, PredOnExpOn) {
+// Prefetch is disabled via field experiment.  Prefetch should be dropped.
+IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionDisabled,
+                       ExperimentDisabled) {
+  CHECK(test_server()->Start());
+  EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
+  // Should not prefetch even if preference is ALWAYS.
+  SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_ALWAYS);
   EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
 }
 
-// Privacy option is on, experiment is off.  Prefetch should be dropped.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOff, PredOnExpOff) {
-  EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
-}
+// Prefetch should be allowed depending on preference and network type.
+IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPrediction, PreferenceWorks) {
+  CHECK(test_server()->Start());
+  // Set real NetworkChangeNotifier singleton aside.
+  scoped_ptr<NetworkChangeNotifier::DisableForTest> disable_for_test(
+      new NetworkChangeNotifier::DisableForTest);
 
-// Privacy option is off, experiment is on.  Prefetch should be dropped.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOffExpOn, PredOffExpOn) {
-  EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
-}
+  // Preference defaults to WIFI_ONLY: prefetch when not on cellular.
+  {
+    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
+    EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
+  }
+  {
+    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
+    EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
+  }
 
-// Privacy option is off, experiment is off.  Prefetch should be dropped.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOffExpOff, PredOffExpOff) {
-  EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
+  // Set preference to ALWAYS: always prefetch.
+  SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_ALWAYS);
+  {
+    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
+    EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
+  }
+  {
+    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
+    EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
+  }
+
+  // Set preference to NEVER: never prefetch.
+  SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_NEVER);
+  {
+    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
+    EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
+  }
+  {
+    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
+    EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
+  }
 }
 
 // Bug 339909: When in incognito mode the browser crashed due to an
 // uninitialized preference member. Verify that it no longer does.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOff, IncognitoTest) {
+IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPrediction, IncognitoTest) {
   Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
   Browser* incognito_browser = new Browser(
       Browser::CreateParams(incognito_profile, browser()->host_desktop_type()));
@@ -165,6 +192,7 @@
   // WebContents for the incognito browser.
   ui_test_utils::OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
 
+  CHECK(test_server()->Start());
   EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser));
 }
 
@@ -173,8 +201,7 @@
 // - if a prefetch is in progress, but the originating renderer is destroyed,
 //   that the pending prefetch request is cleaned up cleanly and does not
 //   result in a crash.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionOnExpOff,
-                       PrefetchFromBrowser) {
+IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPrediction, PrefetchFromBrowser) {
   const GURL kHangingUrl("http://hanging-url.com");
   base::RunLoop loop_;
   BrowserThread::PostTask(BrowserThread::IO,
diff --git a/chrome/browser/prefs/incognito_mode_prefs.cc b/chrome/browser/prefs/incognito_mode_prefs.cc
index 3b7b327..1861ac1 100644
--- a/chrome/browser/prefs/incognito_mode_prefs.cc
+++ b/chrome/browser/prefs/incognito_mode_prefs.cc
@@ -82,6 +82,9 @@
 
 // static
 bool IncognitoModePrefs::CanOpenBrowser(Profile* profile) {
+  if (profile->IsGuestSession())
+    return true;
+
   switch (GetAvailability(profile->GetPrefs())) {
     case IncognitoModePrefs::ENABLED:
       return true;
diff --git a/chrome/browser/prerender/prerender_manager.cc b/chrome/browser/prerender/prerender_manager.cc
index ea4bba1..3627820 100644
--- a/chrome/browser/prerender/prerender_manager.cc
+++ b/chrome/browser/prerender/prerender_manager.cc
@@ -238,8 +238,7 @@
 
 PrerenderManager::PrerenderManager(Profile* profile,
                                    PrerenderTracker* prerender_tracker)
-    : enabled_(profile && profile->GetPrefs() &&
-          profile->GetPrefs()->GetBoolean(prefs::kNetworkPredictionEnabled)),
+    : enabled_(true),
       profile_(profile),
       prerender_tracker_(prerender_tracker),
       prerender_contents_factory_(PrerenderContents::CreateFactory()),
@@ -1862,24 +1861,9 @@
 bool PrerenderManager::IsEnabled() const {
   DCHECK(CalledOnValidThread());
 
-  // TODO(bnc): remove conditional as per crbug.com/334602.
-  if (profile_ && profile_->GetPrefs() &&
-        profile_->GetPrefs()->GetInteger(prefs::kNetworkPredictionOptions) !=
-        chrome_browser_net::NETWORK_PREDICTION_UNSET) {
-    return chrome_browser_net::CanPrefetchAndPrerenderUI(profile_->GetPrefs());
-  }
-  // TODO(bnc): remove rest of method as per crbug.com/334602.
   if (!enabled_)
     return false;
-  for (std::list<const PrerenderCondition*>::const_iterator it =
-           prerender_conditions_.begin();
-       it != prerender_conditions_.end();
-       ++it) {
-    const PrerenderCondition* condition = *it;
-    if (!condition->CanPrerender())
-      return false;
-  }
-  return true;
+  return chrome_browser_net::CanPrefetchAndPrerenderUI(profile_->GetPrefs());
 }
 
 void PrerenderManager::AddProfileNetworkBytesIfEnabled(int64 bytes) {
diff --git a/chrome/browser/profiles/gaia_info_update_service.cc b/chrome/browser/profiles/gaia_info_update_service.cc
index a68006b..010756c 100644
--- a/chrome/browser/profiles/gaia_info_update_service.cc
+++ b/chrome/browser/profiles/gaia_info_update_service.cc
@@ -159,6 +159,7 @@
   if (username.empty()) {
     // Unset the old user's GAIA info.
     cache.SetGAIANameOfProfileAtIndex(profile_index, base::string16());
+    cache.SetGAIAGivenNameOfProfileAtIndex(profile_index, base::string16());
     // The profile index may have changed.
     profile_index = cache.GetIndexOfProfileWithPath(profile_->GetPath());
     if (profile_index == std::string::npos)
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc
index 209ba2a..6159efe 100644
--- a/chrome/browser/profiles/off_the_record_profile_impl.cc
+++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -124,8 +124,10 @@
   BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
       this);
 
-  DCHECK_NE(IncognitoModePrefs::DISABLED,
-            IncognitoModePrefs::GetAvailability(profile_->GetPrefs()));
+  // Guest profiles may always be OTR. Check IncognitoModePrefs otherwise.
+  DCHECK(profile_->IsGuestSession() ||
+         IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) !=
+             IncognitoModePrefs::DISABLED);
 
 #if defined(OS_ANDROID) || defined(OS_IOS)
   UseSystemProxy();
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index 8aaa047..c5ba808 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -169,13 +169,10 @@
     }
   }
 
-  // If needed, start downloading the high-res avatars.
-  if (switches::IsNewAvatarMenu()) {
-    for (size_t i = 0; i < GetNumberOfProfiles(); i++) {
-      DownloadHighResAvatar(GetAvatarIconIndexOfProfileAtIndex(i),
-                            GetPathOfProfileAtIndex(i));
-    }
-  }
+  // If needed, start downloading the high-res avatars and migrate any legacy
+  // profile names.
+  if (switches::IsNewAvatarMenu())
+    MigrateLegacyProfileNamesAndDownloadAvatars();
 }
 
 ProfileInfoCache::~ProfileInfoCache() {
@@ -1067,3 +1064,45 @@
   delete avatar_images_downloads_in_progress_[file_name];
   avatar_images_downloads_in_progress_[file_name] = NULL;
 }
+
+void ProfileInfoCache::MigrateLegacyProfileNamesAndDownloadAvatars() {
+  DCHECK(switches::IsNewAvatarMenu());
+
+  // Only do this on desktop platforms.
+#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_CHROMEOS)
+  // Migrate any legacy profile names ("First user", "Default Profile") to
+  // new style default names ("Person 1"). The problem here is that every
+  // time you rename a profile, the ProfileInfoCache sorts itself, so
+  // whatever you were iterating through is no longer valid. We need to
+  // save a list of the profile paths (which thankfully do not change) that
+  // need to be renamed. We also can't pre-compute the new names, as they
+  // depend on the names of all the other profiles in the info cache, so they
+  // need to be re-computed after each rename.
+  std::vector<base::FilePath> profiles_to_rename;
+
+  const base::string16 default_profile_name = base::i18n::ToLower(
+      l10n_util::GetStringUTF16(IDS_DEFAULT_PROFILE_NAME));
+  const base::string16 default_legacy_profile_name = base::i18n::ToLower(
+      l10n_util::GetStringUTF16(IDS_LEGACY_DEFAULT_PROFILE_NAME));
+
+  for (size_t i = 0; i < GetNumberOfProfiles(); i++) {
+    // If needed, start downloading the high-res avatar for this profile.
+    DownloadHighResAvatar(GetAvatarIconIndexOfProfileAtIndex(i),
+                          GetPathOfProfileAtIndex(i));
+
+    base::string16 name = base::i18n::ToLower(GetNameOfProfileAtIndex(i));
+    if (name == default_profile_name || name == default_legacy_profile_name)
+      profiles_to_rename.push_back(GetPathOfProfileAtIndex(i));
+  }
+
+  // Rename the necessary profiles.
+  std::vector<base::FilePath>::const_iterator it;
+  for (it = profiles_to_rename.begin(); it != profiles_to_rename.end(); ++it) {
+    size_t profile_index = GetIndexOfProfileWithPath(*it);
+    SetProfileIsUsingDefaultNameAtIndex(profile_index, true);
+    // This will assign a new "Person %d" type name and re-sort the cache.
+    SetNameOfProfileAtIndex(profile_index, ChooseNameForNewProfile(
+        GetAvatarIconIndexOfProfileAtIndex(profile_index)));
+  }
+#endif
+}
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
index f8c4390..41fc3df 100644
--- a/chrome/browser/profiles/profile_info_cache.h
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -206,6 +206,11 @@
   void OnAvatarPictureSaved(const std::string& file_name,
                             const base::FilePath& profile_path);
 
+  // Migrate any legacy profile names ("First user", "Default Profile") to
+  // new style default names ("Person 1"), and download and high-res avatars
+  // used by the profiles.
+  void MigrateLegacyProfileNamesAndDownloadAvatars();
+
   PrefService* prefs_;
   std::vector<std::string> sorted_keys_;
   base::FilePath user_data_dir_;
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index ab25357..9fa123c 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -590,4 +590,85 @@
   EXPECT_TRUE(base::DeleteFile(icon_path, true));
   EXPECT_FALSE(base::PathExists(icon_path));
 }
+
+TEST_F(ProfileInfoCacheTest, MigrateLegacyProfileNamesWithNewAvatarMenu) {
+  switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
+  EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
+
+  base::FilePath path_1 = GetProfilePath("path_1");
+  GetCache()->AddProfileToCache(path_1, ASCIIToUTF16("Default Profile"),
+                                base::string16(), 0, std::string());
+  base::FilePath path_2 = GetProfilePath("path_2");
+  GetCache()->AddProfileToCache(path_2, ASCIIToUTF16("First user"),
+                                base::string16(), 1, std::string());
+  base::string16 name_3 = ASCIIToUTF16("Lemonade");
+  base::FilePath path_3 = GetProfilePath("path_3");
+  GetCache()->AddProfileToCache(path_3, name_3,
+                                base::string16(), 2, std::string());
+  base::string16 name_4 = ASCIIToUTF16("Batman");
+  base::FilePath path_4 = GetProfilePath("path_4");
+  GetCache()->AddProfileToCache(path_4, name_4,
+                                base::string16(), 3, std::string());
+  base::string16 name_5 = ASCIIToUTF16("Person 2");
+  base::FilePath path_5 = GetProfilePath("path_5");
+  GetCache()->AddProfileToCache(path_5, name_5,
+                                base::string16(), 2, std::string());
+
+  EXPECT_EQ(5U, GetCache()->GetNumberOfProfiles());
+
+
+  ResetCache();
+
+  // Legacy profile names like "Default Profile" and "First user" should be
+  // migrated to "Person %n" type names.
+  EXPECT_EQ(ASCIIToUTF16("Person 1"), GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_1)));
+  EXPECT_EQ(ASCIIToUTF16("Person 3"), GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_2)));
+
+  // Other profile names should not be migrated even if they're the old
+  // default cartoon profile names.
+  EXPECT_EQ(name_3, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_3)));
+  EXPECT_EQ(name_4, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_4)));
+  EXPECT_EQ(name_5, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_5)));
+}
 #endif
+
+TEST_F(ProfileInfoCacheTest,
+       DontMigrateLegacyProfileNamesWithoutNewAvatarMenu) {
+  EXPECT_EQ(0U, GetCache()->GetNumberOfProfiles());
+
+  base::string16 name_1 = ASCIIToUTF16("Default Profile");
+  base::FilePath path_1 = GetProfilePath("path_1");
+  GetCache()->AddProfileToCache(path_1, name_1,
+                                base::string16(), 0, std::string());
+  base::string16 name_2 = ASCIIToUTF16("First user");
+  base::FilePath path_2 = GetProfilePath("path_2");
+  GetCache()->AddProfileToCache(path_2, name_2,
+                                base::string16(), 1, std::string());
+  base::string16 name_3 = ASCIIToUTF16("Lemonade");
+  base::FilePath path_3 = GetProfilePath("path_3");
+  GetCache()->AddProfileToCache(path_3, name_3,
+                                base::string16(), 2, std::string());
+  base::string16 name_4 = ASCIIToUTF16("Batman");
+  base::FilePath path_4 = GetProfilePath("path_4");
+  GetCache()->AddProfileToCache(path_4, name_4,
+                                base::string16(), 3, std::string());
+  EXPECT_EQ(4U, GetCache()->GetNumberOfProfiles());
+
+  ResetCache();
+
+  // Profile names should have been preserved.
+  EXPECT_EQ(name_1, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_1)));
+  EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_2)));
+  EXPECT_EQ(name_3, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_3)));
+  EXPECT_EQ(name_4, GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetIndexOfProfileWithPath(path_4)));
+}
+
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 1645dc1..6e47eb3 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -1085,17 +1085,27 @@
   EXPECT_EQ(default_profile_name,
             profiles::GetAvatarNameForProfile(profile1->GetPath()));
 
-  // We should display the actual profile name for signed in profiles.
+  // For a signed in profile with a default name we still display
+  // IDS_SINGLE_PROFILE_DISPLAY_NAME.
   cache.SetUserNameOfProfileAtIndex(0, ASCIIToUTF16("user@gmail.com"));
   EXPECT_EQ(profile_name1, cache.GetNameOfProfileAtIndex(0));
-  EXPECT_EQ(profile_name1,
+  EXPECT_EQ(default_profile_name,
             profiles::GetAvatarNameForProfile(profile1->GetPath()));
 
+  // For a signed in profile with a non-default Gaia given name we display the
+  // Gaia given name.
+  cache.SetUserNameOfProfileAtIndex(0, ASCIIToUTF16("user@gmail.com"));
+  const base::string16 gaia_given_name(ASCIIToUTF16("given name"));
+  cache.SetGAIAGivenNameOfProfileAtIndex(0, gaia_given_name);
+  EXPECT_EQ(gaia_given_name, cache.GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(gaia_given_name,
+      profiles::GetAvatarNameForProfile(profile1->GetPath()));
+
   // Multiple profiles means displaying the actual profile names.
   const base::string16 profile_name2 = cache.ChooseNameForNewProfile(1);
   Profile* profile2 = AddProfileToCache(profile_manager,
                                         "path_2", profile_name2);
-  EXPECT_EQ(profile_name1,
+  EXPECT_EQ(gaia_given_name,
             profiles::GetAvatarNameForProfile(profile1->GetPath()));
   EXPECT_EQ(profile_name2,
             profiles::GetAvatarNameForProfile(profile2->GetPath()));
@@ -1105,7 +1115,7 @@
                                               ProfileManager::CreateCallback());
   // Spin the message loop so that all the callbacks can finish running.
   base::RunLoop().RunUntilIdle();
-  EXPECT_EQ(profile_name1,
+  EXPECT_EQ(gaia_given_name,
             profiles::GetAvatarNameForProfile(profile1->GetPath()));
 }
 #endif  // !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/profiles/profiles_state.cc b/chrome/browser/profiles/profiles_state.cc
index 8552cdf..864ac7e 100644
--- a/chrome/browser/profiles/profiles_state.cc
+++ b/chrome/browser/profiles/profiles_state.cc
@@ -59,21 +59,19 @@
     if (index == std::string::npos)
       return l10n_util::GetStringUTF16(IDS_SINGLE_PROFILE_DISPLAY_NAME);
 
-    // Using the --new-profile-management flag, there's a couple of rules
-    // about what the avatar button displays. If there's a single, local
-    // profile, with a default name (i.e. of the form Person %d), it should
-    // display IDS_SINGLE_PROFILE_DISPLAY_NAME. If this is a signed in profile,
-    // or the user has edited the profile name, or there are multiple profiles,
-    // it will return the actual name  of the profile.
+    // Using the --new-avatar-menu flag, there's a couple of rules about what
+    // the avatar button displays. If there's a single profile, with a default
+    // name (i.e. of the form Person %d) not manually set, it should display
+    // IDS_SINGLE_PROFILE_DISPLAY_NAME. Otherwise, it will return the actual
+    // name of the profile.
     base::string16 profile_name = cache.GetNameOfProfileAtIndex(index);
-    bool has_default_name = cache.ProfileIsUsingDefaultNameAtIndex(index);
+    bool has_default_name = cache.ProfileIsUsingDefaultNameAtIndex(index) &&
+        cache.IsDefaultProfileName(profile_name);
 
-    if (cache.GetNumberOfProfiles() == 1 && has_default_name &&
-        cache.GetUserNameOfProfileAtIndex(index).empty()) {
+    if (cache.GetNumberOfProfiles() == 1 && has_default_name)
       display_name = l10n_util::GetStringUTF16(IDS_SINGLE_PROFILE_DISPLAY_NAME);
-    } else {
+    else
       display_name = profile_name;
-    }
   }
   return display_name;
 }
@@ -93,15 +91,19 @@
 
 void UpdateProfileName(Profile* profile,
                        const base::string16& new_profile_name) {
-  PrefService* pref_service = profile->GetPrefs();
   ProfileInfoCache& cache =
       g_browser_process->profile_manager()->GetProfileInfoCache();
+  size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
+  if (profile_index == std::string::npos)
+    return;
+
+  if (new_profile_name == cache.GetNameOfProfileAtIndex(profile_index))
+    return;
 
   // This is only called when updating the profile name through the UI,
   // so we can assume the user has done this on purpose.
-  size_t profile_index = cache.GetIndexOfProfileWithPath(profile->GetPath());
-  if (profile_index != std::string::npos)
-    pref_service->SetBoolean(prefs::kProfileUsingDefaultName, false);
+  PrefService* pref_service = profile->GetPrefs();
+  pref_service->SetBoolean(prefs::kProfileUsingDefaultName, false);
 
   // Updating the profile preference will cause the cache to be updated for
   // this preference.
diff --git a/chrome/browser/resources/chromeos/echo/manifest.json b/chrome/browser/resources/chromeos/echo/manifest.json
index 4a32569..fc7b750 100644
--- a/chrome/browser/resources/chromeos/echo/manifest.json
+++ b/chrome/browser/resources/chromeos/echo/manifest.json
@@ -40,7 +40,7 @@
   "externally_connectable": {
     "ids": ["*"],
     "matches": [
-      "*://www.google.com/*/chrome/devices/goodies.html*"
+      "*://www.google.com/*chrome/devices/goodies.html*"
     ]
   }
 }
diff --git a/chrome/browser/resources/chromeos/genius_app/manifest.json b/chrome/browser/resources/chromeos/genius_app/manifest.json
index 11d13b5..e9269ce 100644
--- a/chrome/browser/resources/chromeos/genius_app/manifest.json
+++ b/chrome/browser/resources/chromeos/genius_app/manifest.json
@@ -25,7 +25,9 @@
   "permissions": [
     "alarms",
     "identity",
+    "identity.email",
     "chromeosInfoPrivate",
+    "fileSystem",
     "firstRunPrivate",
     "management",
     "metricsPrivate",
@@ -45,7 +47,6 @@
   "oauth2": {
     "client_id": "929143421683.apps.googleusercontent.com",
     "scopes": [
-        "https://www.googleapis.com/auth/userinfo.email",
         "https://www.googleapis.com/auth/supportcontent",
         "https://www.google.com/accounts/OAuthLogin"
     ]
@@ -58,6 +59,13 @@
       ],
       "title": "Open Help Article"
     },
+    "hts": {
+      "matches": [
+        "https://support.google.com/chromeos-gethelp/rts*",
+        "https://support.google.com/chromeos-gethelp/helpouts*"
+      ],
+      "title": "Contact Support"
+    },
     "home": {
       "matches": [
         "https://support.google.com/chromeos-gethelp",
diff --git a/chrome/browser/resources/cryptotoken/manifest.json b/chrome/browser/resources/cryptotoken/manifest.json
index 43ab8d4..3764eab 100644
--- a/chrome/browser/resources/cryptotoken/manifest.json
+++ b/chrome/browser/resources/cryptotoken/manifest.json
@@ -19,6 +19,22 @@
           "productId": 512
         },
         {
+          "vendorId": 4176,
+          "productId": 275
+        },
+        {
+          "vendorId": 4176,
+          "productId": 277
+        },
+        {
+          "vendorId": 4176,
+          "productId": 288
+        },
+        {
+          "vendorId": 4176,
+          "productId": 1025
+        },
+        {
           "vendorId": 9601,
           "productId": 61904
         },
diff --git a/chrome/browser/resources/cryptotoken/usbgnubbydevice.js b/chrome/browser/resources/cryptotoken/usbgnubbydevice.js
index 09b3909..089ca15 100644
--- a/chrome/browser/resources/cryptotoken/usbgnubbydevice.js
+++ b/chrome/browser/resources/cryptotoken/usbgnubbydevice.js
@@ -374,26 +374,29 @@
 };
 
 /**
+ * @const
+ */
+UsbGnubbyDevice.WINUSB_VID_PIDS = [
+  {'vendorId': 4176, 'productId': 529}  // Yubico WinUSB
+];
+
+/**
  * @param {function(Array)} cb Enumerate callback
  */
 UsbGnubbyDevice.enumerate = function(cb) {
-  var permittedDevs;
   var numEnumerated = 0;
   var allDevs = [];
 
   function enumerated(devs) {
     allDevs = allDevs.concat(devs);
-    if (++numEnumerated == permittedDevs.length) {
+    if (++numEnumerated == UsbGnubbyDevice.WINUSB_VID_PIDS.length) {
       cb(allDevs);
     }
   }
 
-  GnubbyDevice.getPermittedUsbDevices(function(devs) {
-    permittedDevs = devs;
-    for (var i = 0; i < devs.length; i++) {
-      chrome.usb.getDevices(devs[i], enumerated);
-    }
-  });
+  for (var i = 0; i < UsbGnubbyDevice.WINUSB_VID_PIDS.length; i++) {
+    chrome.usb.getDevices(UsbGnubbyDevice.WINUSB_VID_PIDS[i], enumerated);
+  }
 };
 
 /**
diff --git a/chrome/browser/resources/easy_unlock/manifest.json b/chrome/browser/resources/easy_unlock/manifest.json
index b64d43f..38c7143 100644
--- a/chrome/browser/resources/easy_unlock/manifest.json
+++ b/chrome/browser/resources/easy_unlock/manifest.json
@@ -24,7 +24,10 @@
     "easyUnlockPrivate",
     "systemPrivate",
     "alarms",
-    "gcm"
+    "gcm",
+    "system.display",
+    "chromeosInfoPrivate",
+    "tabs"
   ],
 
   "app": {
diff --git a/chrome/browser/resources/gesture_config.css b/chrome/browser/resources/gesture_config.css
index eec68a9..5b70596 100644
--- a/chrome/browser/resources/gesture_config.css
+++ b/chrome/browser/resources/gesture_config.css
@@ -3,7 +3,7 @@
  * found in the LICENSE file. */
 
 body {
-  font-family: 'Noto Sans UI', 'Droid Sans Fallback', sans-serif;
+  font-family: 'Noto Sans UI', sans-serif;
   font-size: 12px;
 }
 
diff --git a/chrome/browser/resources/help_app/manifest.json b/chrome/browser/resources/help_app/manifest.json
index 89d4bbf..34de5e7 100644
--- a/chrome/browser/resources/help_app/manifest.json
+++ b/chrome/browser/resources/help_app/manifest.json
@@ -6,5 +6,26 @@
   "default_locale": "en",
   "manifest_version": 2,
   "content_security_policy": "default-src 'self'; img-src 'self' data:;",
+  "background": {
+    "scripts": [
+      "js/background-bundle.js"
+    ],
+    "persistent": false
+  },
+  "content_scripts": [
+    {
+      "js": ["js/content_script_head.js"],
+      "matches": ["https://support.google.com/chromebook/*"],
+      "run_at": "document_start"
+    },
+    {
+      "js": ["js/content_script_foot.js"],
+      "matches": ["https://support.google.com/chromebook/*"],
+      "run_at": "document_idle"
+    }
+  ],
+  "permissions": [
+    "storage"
+  ],
   "incognito": "split"
 }
diff --git a/chrome/browser/resources/local_ntp/local_ntp.css b/chrome/browser/resources/local_ntp/local_ntp.css
index 2e2acd0..9cdab2e 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.css
+++ b/chrome/browser/resources/local_ntp/local_ntp.css
@@ -15,7 +15,16 @@
   text-align: -webkit-center;
 }
 
+#ntp-contents.classical {
+  margin-top: 157px;
+}
+
+#ntp-contents.md {
+  margin-top: 157px;
+}
+
 .non-google-page #ntp-contents {
+  margin-top: 0;
   position: absolute;
   top: calc(50% - 155px);
   width: 100%;
@@ -41,12 +50,14 @@
   background-size: 269px 95px;
   height: 95px;
   margin-bottom: 24px;
-  margin-top: 157px;
   width: 269px;
 }
 
 body.alternate-logo #logo {
-  background-image: url('images/white_google_logo.png@2x');
+  -webkit-mask-image: url('images/google_logo.png@2x');
+  -webkit-mask-repeat: no-repeat;
+  -webkit-mask-size: 100%;
+  background: #eee;
 }
 
 #fakebox {
@@ -61,7 +72,7 @@
   font-size: 18px;
   height: 36px;
   line-height: 36px;
-  max-width: 620px;
+  max-width: 672px;
   position: relative;
   /* #fakebox width (here and below) should be 2px less than #mv-tiles
      to account for its border. */
@@ -103,12 +114,17 @@
   color: #bbb;
   font-family: arial, sans-serif;
   font-size: 16px;
-  height: 16px;
+  height: 100%;
   left: 9px;
   margin-top: 1px;
+  overflow: hidden;
   position: absolute;
+  text-align: left;
+  text-overflow: ellipsis;
   vertical-align: middle;
-  visibility: hidden;
+  visibility: inherit;
+  white-space: nowrap;
+  width: calc(100% - 2 * 9px);
 }
 
 body[dir=rtl] #fakebox-text {
@@ -142,7 +158,7 @@
 
 body.fakebox-drag-focused #fakebox-text,
 body.fakebox-focused #fakebox-text {
-  visibility: inherit;
+  visibility: hidden;
 }
 
 body.fakebox-drag-focused #cursor {
@@ -164,7 +180,7 @@
 }
 
 .md #most-visited {
-  margin-top: 50px;
+  margin-top: 64px;
 }
 
 #mv-tiles {
@@ -183,8 +199,8 @@
 }
 
 .md #mv-tiles {
-  height: calc(2 * 126px);
-  line-height: 126px;
+  height: calc(2 * 146px);
+  line-height: 146px;
 }
 
 .mv-tile {
@@ -214,12 +230,12 @@
 }
 
 .md .mv-tile {
-  background: #f2f2f2;
+  background: rgb(242,242,242);
   border-radius: 1px;
-  height: 114px;
-  margin-left: 6px;
-  margin-right: 6px;
-  width: 146px;
+  height: 130px;
+  margin-left: 8px;
+  margin-right: 8px;
+  width: 156px;
 }
 
 .md .mv-page-ready {
@@ -228,7 +244,7 @@
 }
 
 .md.dark .mv-tile {
-  background: #333;
+  background: rgb(51,51,51);
 }
 
 .mv-tile-inner {
@@ -274,8 +290,8 @@
 .md .mv-mask {
   border-color: transparent;
   border-radius: 2px;
-  height: 112px;
-  width: 144px;
+  height: calc(130px - 2px);
+  width: calc(156px - 2px);
 }
 
 /* Styling border. */
@@ -304,11 +320,11 @@
 }
 
 /* Styling shadow. */
-.md .mv-page-ready .mv-mask {
+.default-theme.md .mv-page-ready .mv-mask {
   -webkit-transition: box-shadow 200ms, border 200ms;
 }
 .default-theme.md .mv-page-ready:hover .mv-mask {
-  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
+  box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1), 0 4px 8px 0 rgba(0,0,0,0.2);
 }
 
 .default-theme..md.dark .mv-page-ready:hover .mv-mask,
@@ -326,7 +342,7 @@
 
 .md .mv-page:focus .mv-mask {
   -webkit-transition: box-shadow 200ms, border 200ms,
-      background-color 100ms ease-in-out, ;
+      background-color 100ms ease-in-out;
   background: rgba(0, 0, 0, 0.3);
   border-color: rgba(0, 0, 0, 0.3);
 }
@@ -346,20 +362,20 @@
 .md .mv-title {
   bottom: auto;
   height: 15px;
-  left: 28px;
-  top: 7px;
-  width: 112px;
+  left: 32px;
+  top: 9px;
+  width: calc(156px - 32px - 4px);
 }
 
 @media (-webkit-min-device-pixel-ratio: 2) {
   .md .mv-title {
-    top: 6px;
+    top: 8px;
   }
 }
 
 body[dir=rtl] .md .mv-title {
   left: auto;
-  right: 28px;
+  right: 32px;
 }
 
 .mv-thumb {
@@ -389,10 +405,10 @@
 .md .mv-thumb,
 .md .mv-thumb-fallback {
   border-radius: 0;
-  height: 82px;
+  height: 94px;
   left: 4px;
-  top: 28px;
-  width: 138px;
+  top: 32px;
+  width: 148px;
 }
 
 body[dir=rtl] .md .mv-thumb,
@@ -402,30 +418,29 @@
 }
 
 .md .mv-thumb-fallback {
-  background: #fff;
-  padding: none;
+  background-color: #fff;
   position: absolute;
 }
 
 .md.dark .mv-thumb-fallback {
-  background: #555;
+  background-color: #555;
 }
 
 .md .mv-thumb-fallback .dot {
-  background: #f2f2f2;
-  border-radius: 16px;
+  background-color: #f2f2f2;
+  border-radius: 8px;
   display: block;
-  height: 32px;
+  height: 16px;
   left: 50%;
-  margin-left: -16px;
-  margin-top: -16px;
+  margin-left: -8px;
+  margin-top: -8px;
   position: absolute;
   top: 50%;
-  width: 32px;
+  width: 16px;
 }
 
 .md.dark .mv-thumb-fallback .dot {
-  background: #333;
+  background-color: #333;
 }
 
 .mv-x-hide .mv-x {
@@ -435,11 +450,8 @@
 /* An X button to blacklist a tile or hide the notification. */
 .mv-x {
   background-color: transparent;
-  background-image: url(images/close_2.png);
   border: none;
-  cursor: default;
-  height: 16px;
-  width: 16px;
+  cursor: pointer;
 }
 
 .mv-page .mv-x {
@@ -448,13 +460,20 @@
   position: absolute;
 }
 
-.mv-x:hover,
-#mv-notice-x:focus {
-  background-image: url(images/close_2_hover.png);
+.classical .mv-x {
+  background-image: url('images/close_2.png');
+  height: 16px;
+  width: 16px;
 }
 
-.mv-x:active {
-  background-image: url(images/close_2_active.png);
+.classical .mv-x:hover,
+.classical #mv-notice-x:focus {
+  background-image: url('images/close_2_hover.png');
+}
+
+.classical .mv-x:active,
+.classical #mv-notice-x:active {
+  background-image: url('images/close_2_active.png');
 }
 
 .classical .mv-page .mv-x {
@@ -462,30 +481,89 @@
   top: 2px;
 }
 
-.md .mv-x {
-  background-color: rgba(187,187,187,0.8);
-  border-radius: 8px;
-}
-
-.md.dark .mv-x {
-  background-color: rgba(119,119,119,0.8);
-}
-
-.md .mv-page .mv-x {
-  right: 4px;
-  top: 5px;
-}
-
 body[dir=rtl] .classical .mv-page .mv-x {
   left: 2px;
   right: auto;
 }
 
+#mv-notice-x {
+  display: inline-block;
+  position: relative;
+}
+
+.md #mv-notice-x {
+  -webkit-transform: translate(0,-8px);
+}
+
+.md .mv-x {
+  height: 32px;
+  width: 32px;
+}
+
+.md .mv-x .mv-x-inner {
+  -webkit-mask-image: -webkit-image-set(
+      url('images/close_3_mask.png') 1x,
+      url('images/close_3_mask.png@2x') 2x);
+  -webkit-mask-repeat: no-repeat;
+  -webkit-mask-size: 10px 10px;
+  background-color: rgba(90,90,90,0.7);
+  height: 10px;
+  left: 50%;
+  margin-left: -5px;
+  margin-top: -5px;
+  position: absolute;
+  top: 50%;
+  width: 10px;
+}
+
+.md.dark .mv-x .mv-x-inner {
+  background-color: rgba(255,255,255,0.7);
+}
+
+.md .mv-x:hover .mv-x-inner,
+.md #mv-notice-x:focus .mv-x-inner {
+  background-color: rgb(90,90,90);
+}
+
+.md.dark .mv-x:hover .mv-x-inner,
+.md.dark #mv-notice-x:focus .mv-x-inner {
+  background-color: rgb(255,255,255);
+}
+
+.md .mv-x:active .mv-x-inner,
+.md #mv-notice-x:active .mv-x-inner {
+  background-color: rgb(66,133,244);
+}
+
+.md.dark .mv-x:active .mv-x-inner,
+.md.dark #mv-notice-x:active .mv-x-inner {
+  background-color: rgba(255,255,255,0.5);
+}
+
+.md .mv-page .mv-x {
+  /* background color needs to match .md .mv-tile */
+  background: linear-gradient(to right, transparent, rgb(242,242,242) 10%);
+  right: 0;
+  top: 0;
+}
+
 body[dir=rtl] .md .mv-page .mv-x {
-  left: 4px;
+  /* background color needs to match .md .mv-tile */
+  background: linear-gradient(to left, transparent, rgb(242,242,242) 10%);
+  left: 0;
   right: auto;
 }
 
+.md.dark .mv-page .mv-x {
+  /* background color needs to match .md.dark .mv-tile */
+  background: linear-gradient(to right, transparent, rgba(51,51,51,0.9) 30%);
+}
+
+body[dir=rtl] .md.dark .mv-page .mv-x {
+  /* background color needs to match .md.dark .mv-tile */
+  background: linear-gradient(to left, transparent, rgba(51,51,51,0.9) 30%);
+}
+
 .mv-page-ready:hover .mv-x {
   -webkit-transition-delay: 500ms;
   opacity: 1;
@@ -509,14 +587,22 @@
 }
 
 .md .mv-favicon {
-  left: 6px;
-  top: 6px;
+  left: 8px;
+  top: 8px;
 }
 
 body[dir=rtl] .md .mv-favicon {
   left: auto;
-  right: 6px;
-  top: 6px;
+  right: 8px;
+  top: 8px;
+}
+
+.md .mv-favicon-fallback {
+  background-image: -webkit-image-set(
+      url('images/ntp_default_favicon.png') 1x,
+      url('images/ntp_default_favicon.png@2x') 2x);
+  background-repeat: no-repeat;
+  background-size: 16px 16px;
 }
 
 /* The notification shown when a tile is blacklisted. */
@@ -529,6 +615,10 @@
 
 #mv-notice span {
   cursor: default;
+  display: inline-block;
+  height: 16px;
+  line-height: 16px;
+  vertical-align: top;
 }
 
 /* Links in the notification. */
@@ -550,6 +640,10 @@
   color: #fff;
 }
 
+.default-theme.dark #mv-notice-links span {
+  color: #fff;
+}
+
 #mv-notice-links .mv-x {
   -webkit-margin-start: 8px;
   outline: none;
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html
index 44e79bb..dd43063 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.html
+++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -21,7 +21,7 @@
         <span id="mv-notice-links">
           <span id="mv-undo" tabIndex="1"></span>
           <span id="mv-restore" tabIndex="1"></span>
-          <button id="mv-notice-x" tabIndex="1" class="mv-x"></button>
+          <div id="mv-notice-x" tabIndex="1" class="mv-x"></div>
         </span>
       </div>
     </div>
diff --git a/chrome/browser/resources/local_ntp/local_ntp.js b/chrome/browser/resources/local_ntp/local_ntp.js
index 26bf34e..c37c0b6 100644
--- a/chrome/browser/resources/local_ntp/local_ntp.js
+++ b/chrome/browser/resources/local_ntp/local_ntp.js
@@ -28,6 +28,7 @@
   ALTERNATE_LOGO: 'alternate-logo', // Shows white logo if required by theme
   BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation
   BLACKLIST_BUTTON: 'mv-x',
+  BLACKLIST_BUTTON_INNER: 'mv-x-inner',
   DARK: 'dark',
   DEFAULT_THEME: 'default-theme',
   DELAYED_HIDE_NOTIFICATION: 'mv-notice-delayed-hide',
@@ -176,13 +177,6 @@
 
 
 /**
- * Stores whether the current theme has a dark background.
- * @type {boolean}
- */
-var isBackgroundDark = false;
-
-
-/**
  * Current number of tiles columns shown based on the window width, including
  * those that just contain filler.
  * @type {number}
@@ -268,6 +262,13 @@
 
 
 /**
+ * The color of the title in RRGGBBAA format.
+ * @type {?string}
+ */
+var titleColor = null;
+
+
+/**
  * Hide most visited tiles for at most this many milliseconds while painting.
  * @type {number}
  * @const
@@ -306,17 +307,19 @@
 
 
 /**
- * Determines whether a theme should be considered to have dark background.
- * @param {ThemeBackgroundInfo} info Theme background information.
- * @return {boolean} Whether the theme has dark background.
+ * Heuristic to determine whether a theme should be considered to be dark, so
+ * the colors of various UI elements can be adjusted.
+ * @param {ThemeBackgroundInfo|undefined} info Theme background information.
+ * @return {boolean} Whether the theme is dark.
  * @private
  */
-function getIsBackgroundDark(info) {
-  if (info.imageUrl)
-    return true;
-  var rgba = info.backgroundColorRgba;
+function getIsThemeDark(info) {
+  if (!info)
+    return false;
+  // Heuristic: light text implies dark theme.
+  var rgba = info.textColorRgba;
   var luminance = 0.3 * rgba[0] + 0.59 * rgba[1] + 0.11 * rgba[2];
-  return luminance < 128;
+  return luminance >= 128;
 }
 
 
@@ -325,20 +328,37 @@
  * @private
  */
 function renderTheme() {
+  var fakeboxText = $(IDS.FAKEBOX_TEXT);
+  if (fakeboxText) {
+    fakeboxText.innerHTML = '';
+    if (NTP_DESIGN.showFakeboxHint &&
+        configData.translatedStrings.searchboxPlaceholder) {
+      fakeboxText.textContent =
+          configData.translatedStrings.searchboxPlaceholder;
+    }
+  }
+
   var info = ntpApiHandle.themeBackgroundInfo;
+  var isThemeDark = getIsThemeDark(info);
+  ntpContents.classList.toggle(CLASSES.DARK, isThemeDark);
   if (!info) {
-    isBackgroundDark = false;
+    titleColor = NTP_DESIGN.titleColor;
     return;
   }
 
-  isBackgroundDark = getIsBackgroundDark(info);
-  ntpContents.classList.toggle(CLASSES.DARK, isBackgroundDark);
+  if (!info.usingDefaultTheme && info.textColorRgba) {
+    titleColor = convertToRRGGBBAAColor(info.textColorRgba);
+  } else {
+    titleColor = isThemeDark ?
+        NTP_DESIGN.titleColorAgainstDark : NTP_DESIGN.titleColor;
+  }
 
   var background = [convertToRGBAColor(info.backgroundColorRgba),
                     info.imageUrl,
                     info.imageTiling,
                     info.imageHorizontalAlignment,
                     info.imageVerticalAlignment].join(' ').trim();
+
   document.body.style.background = background;
   document.body.classList.toggle(CLASSES.ALTERNATE_LOGO, info.alternateLogo);
   updateThemeAttribution(info.attributionUrl);
@@ -366,7 +386,6 @@
 function setCustomThemeStyle(opt_themeInfo) {
   var customStyleElement = $(IDS.CUSTOM_THEME_STYLE);
   var head = document.head;
-
   if (opt_themeInfo && !opt_themeInfo.usingDefaultTheme) {
     ntpContents.classList.remove(CLASSES.DEFAULT_THEME);
     var themeStyle =
@@ -444,6 +463,19 @@
 
 
  /**
+ * Converts an Array of color components into RRGGBBAA format.
+ * @param {Array.<number>} color Array of rgba color components.
+ * @return {string} Color string in RRGGBBAA format.
+ * @private
+ */
+function convertToRRGGBBAAColor(color) {
+  return color.map(function(t) {
+    return ('0' + t.toString(16)).slice(-2);  // To 2-digit, 0-padded hex.
+  }).join('');
+}
+
+
+ /**
  * Converts an Array of color components into RGBA format "rgba(R,G,B,A)".
  * @param {Array.<number>} color Array of rgba color components.
  * @return {string} CSS color in RGBA format.
@@ -585,8 +617,6 @@
 function getMostVisitedTitleIframeUrl(rid, position) {
   var url = 'chrome-search://most-visited/' +
       encodeURIComponent(MOST_VISITED_TITLE_IFRAME);
-  var titleColor = isBackgroundDark ? NTP_DESIGN.titleColorAgainstDark :
-      NTP_DESIGN.titleColor;
   var params = [
       'rid=' + encodeURIComponent(rid),
       'f=' + encodeURIComponent(NTP_DESIGN.fontFamily),
@@ -632,6 +662,11 @@
 function createTile(page, position) {
   var tileElem = document.createElement('div');
   tileElem.classList.add(CLASSES.TILE);
+  // Prevent tile from being selected (and highlighted) when areas outside the
+  // <iframe>s are clicked.
+  tileElem.addEventListener('mousedown', function(e) {
+    e.preventDefault();
+  });
   var innerElem = createAndAppendElement(tileElem, 'div', CLASSES.TILE_INNER);
 
   if (page) {
@@ -694,6 +729,8 @@
     // The button used to blacklist this page.
     var blacklistButton = createAndAppendElement(
         innerElem, 'div', CLASSES.BLACKLIST_BUTTON);
+    createAndAppendElement(
+        blacklistButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
     var blacklistFunction = generateBlacklistFunction(rid);
     blacklistButton.addEventListener('click', blacklistFunction);
     blacklistButton.title = configData.translatedStrings.removeThumbnailTooltip;
@@ -757,6 +794,7 @@
  */
 function hideNotification() {
   notification.classList.add(CLASSES.HIDE_NOTIFICATION);
+  notification.classList.remove(CLASSES.DELAYED_HIDE_NOTIFICATION);
 }
 
 
@@ -785,11 +823,11 @@
 
 
 /**
- * Resizes elements because the number of tile columns may need to change in
- * response to resizing. Also shows or hides extra tiles tiles according to the
- * new width of the page.
+ * Recomputes the number of tile columns, and width of various contents based
+ * on the width of the window.
+ * @return {boolean} Whether the number of tile columns has changed.
  */
-function onResize() {
+function updateContentWidth() {
   var tileRequiredWidth = NTP_DESIGN.tileWidth + NTP_DESIGN.tileMargin;
   // If innerWidth is zero, then use the maximum snap size.
   var maxSnapSize = MAX_NUM_COLUMNS * tileRequiredWidth -
@@ -804,14 +842,28 @@
   else if (newNumColumns > MAX_NUM_COLUMNS)
     newNumColumns = MAX_NUM_COLUMNS;
 
-  if (numColumnsShown != newNumColumns) {
-    numColumnsShown = newNumColumns;
-    var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
-    tilesContainer.style.width = tilesContainerWidth + 'px';
-    if (fakebox) {
-      fakebox.style.width =  // -2 to account for border.
-          (tilesContainerWidth - NTP_DESIGN.tileMargin - 2) + 'px';
-    }
+  if (numColumnsShown === newNumColumns)
+    return false;
+
+  numColumnsShown = newNumColumns;
+  var tilesContainerWidth = numColumnsShown * tileRequiredWidth;
+  tilesContainer.style.width = tilesContainerWidth + 'px';
+  if (fakebox) {
+    // -2 to account for border.
+    var fakeboxWidth = (tilesContainerWidth - NTP_DESIGN.tileMargin - 2);
+    fakebox.style.width = fakeboxWidth + 'px';
+  }
+  return true;
+}
+
+
+/**
+ * Resizes elements because the number of tile columns may need to change in
+ * response to resizing. Also shows or hides extra tiles tiles according to the
+ * new width of the page.
+ */
+function onResize() {
+  if (updateContentWidth()) {
     // Render without clearing tiles.
     renderAndShowTiles();
   }
@@ -1000,11 +1052,7 @@
     var fakeboxHtml = [];
     fakeboxHtml.push('<input id="' + IDS.FAKEBOX_INPUT +
         '" autocomplete="off" tabindex="-1" aria-hidden="true">');
-    if (NTP_DESIGN.showFakeboxHint &&
-        configData.translatedStrings.searchboxPlaceholder) {
-      fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '">' +
-          configData.translatedStrings.searchboxPlaceholder + '</div>');
-    }
+    fakeboxHtml.push('<div id="' + IDS.FAKEBOX_TEXT + '"></div>');
     fakeboxHtml.push('<div id="cursor"></div>');
     fakebox.innerHTML = fakeboxHtml.join('');
 
@@ -1014,6 +1062,9 @@
     document.body.classList.add(CLASSES.NON_GOOGLE_PAGE);
   }
 
+  // Hide notifications after fade out, so we can't focus on links via keyboard.
+  notification.addEventListener('webkitTransitionEnd', hideNotification);
+
   var notificationMessage = $(IDS.NOTIFICATION_MESSAGE);
   notificationMessage.textContent =
       configData.translatedStrings.thumbnailRemovedNotification;
@@ -1033,10 +1084,12 @@
       configData.translatedStrings.attributionIntro;
 
   var notificationCloseButton = $(IDS.NOTIFICATION_CLOSE_BUTTON);
+  createAndAppendElement(
+      notificationCloseButton, 'div', CLASSES.BLACKLIST_BUTTON_INNER);
   notificationCloseButton.addEventListener('click', hideNotification);
 
   window.addEventListener('resize', onResize);
-  onResize();
+  updateContentWidth();
 
   var topLevelHandle = getEmbeddedSearchApiHandle();
 
diff --git a/chrome/browser/resources/local_ntp/local_ntp_design.js b/chrome/browser/resources/local_ntp/local_ntp_design.js
index ec8db73..7434209 100644
--- a/chrome/browser/resources/local_ntp/local_ntp_design.js
+++ b/chrome/browser/resources/local_ntp/local_ntp_design.js
@@ -19,13 +19,13 @@
  * fontSize: Font size to use for the <iframe>s, in px.
  * tileWidth: The width of each suggestion tile, in px.
  * tileMargin: Spacing between successive tiles, in px.
- * titleColor: The RRGGBB color of title text.
- * titleColorAgainstDark: The RRGGBB color of title text against a dark theme.
+ * titleColor: The RRGGBBAA color of title text.
+ * titleColorAgainstDark: The RRGGBBAA color of title text against a dark theme.
  * titleTextAlign: (Optional) The alignment of title text. If unspecified, the
  *   default value is 'center'.
  * titleTextFade: (Optional) The number of pixels beyond which title
  *   text begins to fade. This overrides the default ellipsis style.
- * thumbnailTextColor: The RRGGBB color that thumbnail <iframe> may use to
+ * thumbnailTextColor: The RRGGBBAA color that thumbnail <iframe> may use to
  *   display text message in place of missing thumbnail.
  * thumbnailFallback: (Optional) A value in THUMBNAIL_FALLBACK to specify the
  *   thumbnail fallback strategy. If unassigned, then the thumbnail.html
@@ -63,13 +63,13 @@
       name: opt_name,
       fontFamily: 'arial, sans-serif',
       fontSize: 12,
-      tileWidth: 146,
-      tileMargin: 12,
-      titleColor: '000000',
-      titleColorAgainstDark: 'd2d2d2',
+      tileWidth: 156,
+      tileMargin: 16,
+      titleColor: '323232ff',
+      titleColorAgainstDark: 'd2d2d2ff',
       titleTextAlign: 'inherit',
-      titleTextFade: 112 - 24,  // 112px wide title with 24 pixel fade at end.
-      thumbnailTextColor: '777777',
+      titleTextFade: 122 - 36,  // 112px wide title with 32 pixel fade at end.
+      thumbnailTextColor: '323232ff',  // Unused.
       thumbnailFallback: THUMBNAIL_FALLBACK.DOT,
       showFakeboxHint: true
     };
@@ -80,11 +80,11 @@
       fontSize: 11,
       tileWidth: 140,
       tileMargin: 20,
-      titleColor: '777777',
-      titleColorAgainstDark: '777777',
+      titleColor: '777777ff',
+      titleColorAgainstDark: '777777ff',
       titleTextAlign: 'center',
       titleTextFade: null,  // Default to ellipsis.
-      thumbnailTextColor: '777777',
+      thumbnailTextColor: '777777ff',
       thumbnailFallback: null,  // Default to false.
       showFakeboxHint: false
     };
diff --git a/chrome/browser/resources/local_ntp/most_visited_util.js b/chrome/browser/resources/local_ntp/most_visited_util.js
index 91aa804..4309179 100644
--- a/chrome/browser/resources/local_ntp/most_visited_util.js
+++ b/chrome/browser/resources/local_ntp/most_visited_util.js
@@ -162,6 +162,38 @@
 
 
 /**
+ * Returns the color to display string with, depending on whether title is
+ * displayed, the current theme, and URL parameters.
+ * @param {Object.<string, string>} params URL parameters specifying style.
+ * @param {boolean} isTitle if the style is for the Most Visited Title.
+ * @return {string} The color to use, in "rgba(#,#,#,#)" format.
+ */
+function getTextColor(params, isTitle) {
+  // 'RRGGBBAA' color format overrides everything.
+  if ('c' in params && params.c.match(/^[0-9A-Fa-f]{8}$/)) {
+    // Extract the 4 pairs of hex digits, map to number, then form rgba().
+    var t = params.c.match(/(..)(..)(..)(..)/).slice(1).map(function(s) {
+      return parseInt(s, 16);
+    });
+    return 'rgba(' + t[0] + ',' + t[1] + ',' + t[2] + ',' + t[3] / 255 + ')';
+  }
+
+  // For backward compatibility with server-side NTP, look at themes directly
+  // and use param.c for non-title or as fallback.
+  var apiHandle = chrome.embeddedSearch.newTabPage;
+  var themeInfo = apiHandle.themeBackgroundInfo;
+  var c = '#777';
+  if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
+    // Read from theme directly
+    c = convertArrayToRGBAColor(themeInfo.textColorRgba) || c;
+  } else if ('c' in params) {
+    c = convertToHexColor(parseInt(params.c, 16)) || c;
+  }
+  return c;
+}
+
+
+/**
  * Decodes most visited styles from URL parameters.
  * - c: A hexadecimal number interpreted as a hex color code.
  * - f: font-family.
@@ -174,18 +206,10 @@
  */
 function getMostVisitedStyles(params, isTitle) {
   var styles = {
-    color: '#777',
+    color: getTextColor(params, isTitle),  // Handles 'c' in params.
     fontFamily: '',
     fontSize: 11
   };
-  var apiHandle = chrome.embeddedSearch.newTabPage;
-  var themeInfo = apiHandle.themeBackgroundInfo;
-  if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
-    styles.color = convertArrayToRGBAColor(themeInfo.textColorRgba) ||
-        styles.color;
-  } else if ('c' in params) {
-    styles.color = convertToHexColor(parseInt(params.c, 16)) || styles.color;
-  }
   if ('f' in params && /^[-0-9a-zA-Z ,]+$/.test(params.f))
     styles.fontFamily = params.f;
   if ('fs' in params && isFinite(parseInt(params.fs, 10)))
diff --git a/chrome/browser/resources/options/browser_options.css b/chrome/browser/resources/options/browser_options.css
index bc945bf..960aa5f 100644
--- a/chrome/browser/resources/options/browser_options.css
+++ b/chrome/browser/resources/options/browser_options.css
@@ -452,10 +452,13 @@
   -webkit-margin-start: 0.6em;
 }
 
-div[guestmode=true] #appearance-section,
-div[guestmode=true] #startup-section,
-div[guestmode=true] #searchBox,
-div[guestmode=true] #reset-profile-settings-section {
+div[guestmode=true] :-webkit-any(
+<if expr="not chromeos">
+    #searchBox,
+</if>
+    #appearance-section,
+    #startup-section,
+    #reset-profile-settings-section) {
   display: none;
 }
 
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 425c2f2..4e9c4ed 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -154,22 +154,6 @@
   <section>
     <h3 id="voice-section-title" i18n-content="sectionTitleVoice" hidden></h3>
     <div id="voice-section-content">
-      <div id="hotword-search" hidden>
-        <div class="checkbox">
-          <span class="controlled-setting-with-label">
-            <input id="hotword-search-enable" pref="hotword.search_enabled_2"
-                metric="Options_HotwordCheckbox" type="checkbox" dialog-pref>
-            <span>
-              <label for="hotword-search-enable"
-                  i18n-values=".innerHTML:hotwordSearchEnable">
-              </label>
-              <span id="hotword-search-setting-indicator"
-                  pref="hotword.search_enabled_2" dialog-pref>
-              </span>
-            </span>
-          </span>
-        </div>
-      </div>
       <div id="hotword-always-on-search" hidden>
         <div class="checkbox">
           <span class="controlled-setting-with-label">
@@ -453,6 +437,22 @@
         </span>
       </div>
 </if>
+      <div id="hotword-search" hidden>
+        <div class="checkbox">
+          <span class="controlled-setting-with-label">
+            <input id="hotword-search-enable" pref="hotword.search_enabled_2"
+                metric="Options_HotwordCheckbox" type="checkbox" dialog-pref>
+            <span>
+              <label for="hotword-search-enable"
+                  i18n-values=".innerHTML:hotwordSearchEnable">
+              </label>
+              <span id="hotword-search-setting-indicator"
+                  pref="hotword.search_enabled_2" dialog-pref>
+              </span>
+            </span>
+          </span>
+        </div>
+      </div>
     </div>
   </section>
 <if expr="chromeos">
@@ -961,7 +961,7 @@
     </div>
   </section>
 </if>
-  <section id="reset-profile-settings-section" hidden>
+  <section id="reset-profile-settings-section">
     <h3 i18n-content="resetProfileSettingsSectionTitle"></h3>
     <div>
       <span class="settings-row" i18n-content="resetProfileSettingsDescription">
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index 618c749..6a7618b 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -1101,7 +1101,6 @@
      * @private
      */
     showHotwordSection_: function(opt_enabled, opt_error) {
-      $('voice-section-title').hidden = false;
       $('hotword-search').hidden = false;
       $('hotword-search-setting-indicator').setError(opt_error);
       if (opt_enabled && opt_error)
@@ -1114,6 +1113,7 @@
      * @private
      */
     showHotwordAlwaysOnSection_: function() {
+      $('voice-section-title').hidden = false;
       $('hotword-always-on-search').hidden = false;
       $('audio-logging').hidden = false;
     },
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js
index 7447b52..0cdd12b 100644
--- a/chrome/browser/resources/options/chromeos/internet_detail.js
+++ b/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -1268,7 +1268,7 @@
           'prl-version',
           getActiveDictionaryValue(data, 'Cellular', 'PRLVersion'));
 
-      var family = getActiveDictionaryValue(data, 'Cellular', 'GSM');
+      var family = getActiveDictionaryValue(data, 'Cellular', 'Family');
       detailsPage.gsm = family == 'GSM';
       if (detailsPage.gsm) {
         $('iccid').textContent =
diff --git a/chrome/browser/resources/options/cookies_list.js b/chrome/browser/resources/options/cookies_list.js
index 0d7d5f4..29159c4 100644
--- a/chrome/browser/resources/options/cookies_list.js
+++ b/chrome/browser/resources/options/cookies_list.js
@@ -173,12 +173,12 @@
         return;
       this.expanded_ = expanded;
       if (expanded) {
+        this.classList.add('show-items');
         var oldExpanded = this.list.expandedItem;
         this.list.expandedItem = this;
         this.updateItems_();
         if (oldExpanded)
           oldExpanded.expanded = false;
-        this.classList.add('show-items');
       } else {
         if (this.list.expandedItem == this) {
           this.list.expandedItem = null;
@@ -535,7 +535,6 @@
       div.className = 'cookie-item';
       // Help out screen readers and such: this is a clickable thing.
       div.setAttribute('role', 'button');
-      div.tabIndex = 0;
       div.textContent = text;
       var apps = this.data.appsProtectingThis;
       if (apps)
diff --git a/chrome/browser/resources/options/cookies_view.css b/chrome/browser/resources/options/cookies_view.css
index ab7a62c..2377e57 100644
--- a/chrome/browser/resources/options/cookies_view.css
+++ b/chrome/browser/resources/options/cookies_view.css
@@ -116,6 +116,7 @@
   -webkit-margin-start: 14em;
   -webkit-padding-start: 7px;
   -webkit-transition: 150ms ease-in-out;
+  display: none;
   height: 0;
   opacity: 0;
   /* Make the cookie items wrap correctly. */
@@ -129,6 +130,7 @@
 }
 
 .show-items .cookie-items {
+  display: block;
   opacity: 1;
 }
 
diff --git a/chrome/browser/resources/user_manager/user_manager.css b/chrome/browser/resources/user_manager/user_manager.css
index c78fb69..cc1dd2e 100644
--- a/chrome/browser/resources/user_manager/user_manager.css
+++ b/chrome/browser/resources/user_manager/user_manager.css
@@ -20,6 +20,13 @@
 .pod {
   box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
   height: 226px;
+  /* On non-retina desktop, the text is blurry if we use the scale3d()
+  inherited from user_pod_row.js */
+  transform: scale(0.9);
+}
+
+podrow[ncolumns='6'] .pod {
+  transform: scale(0.8);
 }
 
 .pod.faded {
@@ -28,11 +35,11 @@
 
 .pod.hovered:not(.focused) {
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
-  opacity: 0.9;
 }
 
 .pod.focused {
   box-shadow: 0 16px 21px rgba(0, 0, 0, 0.2);
+  transform: scale(1) !important;
 }
 
 .pod.focused.locked {
@@ -136,6 +143,9 @@
 .action-box-area {
   background-color: #f5f5f5;
   height: 24px;
+  /* Because of crbug.com/406529, the text in the .name div is janky if there's
+  an opacity transition in this div. */
+  transition: none;
   width: 24px;
 }
 
@@ -158,3 +168,14 @@
 .action-box-area.active .action-box-button {
   border-top: 6px solid #4c4c4c;
 }
+
+.action-box-remove-user-warning .remove-warning-button {
+  height: 30px;
+}
+
+.action-box-remove-user-warning .remove-warning-button:focus {
+  /* Override the default blue border inherited from
+  button.custom-appearance:focus. */
+  border: 1px solid transparent !important;
+  box-shadow: inset 0 0 0 1px #fff;
+}
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index 2029b51..faf6e5f 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -59,9 +59,11 @@
   { "images/close_2_hover.png", IDR_CLOSE_2_H, "image/png" },
   { "images/close_2_active.png", IDR_CLOSE_2_P, "image/png" },
   { "images/close_2_white.png", IDR_CLOSE_2_MASK, "image/png" },
+  { "images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png" },
   { "images/google_logo.png", IDR_LOCAL_NTP_IMAGES_LOGO_PNG, "image/png" },
   { "images/white_google_logo.png",
     IDR_LOCAL_NTP_IMAGES_WHITE_LOGO_PNG, "image/png" },
+  { "images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png" },
 };
 
 // Strips any query parameters from the specified path.
diff --git a/chrome/browser/search/suggestions/suggestions_source.cc b/chrome/browser/search/suggestions/suggestions_source.cc
index aceabcc..a79589a 100644
--- a/chrome/browser/search/suggestions/suggestions_source.cc
+++ b/chrome/browser/search/suggestions/suggestions_source.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/search/suggestions/suggestions_service_factory.h"
 #include "chrome/common/url_constants.h"
 #include "components/suggestions/suggestions_service.h"
+#include "components/suggestions/suggestions_utils.h"
 #include "net/base/escape.h"
 #include "ui/base/l10n/time_format.h"
 #include "ui/gfx/codec/png_codec.h"
@@ -126,7 +127,10 @@
     return;
   }
 
+  // Since it's a debugging page, it's fine to specify that sync state is
+  // initialized.
   suggestions_service->FetchSuggestionsData(
+      INITIALIZED_ENABLED_HISTORY,
       base::Bind(&SuggestionsSource::OnSuggestionsAvailable,
                  weak_ptr_factory_.GetWeakPtr(), callback));
 }
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
index 13816fc..fa03b4a 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler.cc
@@ -28,6 +28,7 @@
     case EasyUnlockScreenlockStateHandler::STATE_PHONE_LOCKED:
     case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY:
     case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE:
+    case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED:
       return "chrome://theme/IDR_EASY_UNLOCK_LOCKED";
     case EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING:
       return "chrome://theme/IDR_EASY_UNLOCK_SPINNER";
@@ -42,13 +43,18 @@
   return state == EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH ||
          state == EasyUnlockScreenlockStateHandler::STATE_NO_PHONE ||
          state == EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY ||
-         state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE;
+         state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE ||
+         state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED;
 }
 
 bool HasAnimation(EasyUnlockScreenlockStateHandler::State state) {
   return state == EasyUnlockScreenlockStateHandler::STATE_BLUETOOTH_CONNECTING;
 }
 
+bool HardlockOnClick(EasyUnlockScreenlockStateHandler::State state) {
+  return state == EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED;
+}
+
 size_t GetTooltipResourceId(EasyUnlockScreenlockStateHandler::State state) {
   switch (state) {
     case EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH:
@@ -64,14 +70,21 @@
     case EasyUnlockScreenlockStateHandler::STATE_PHONE_NOT_NEARBY:
       return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_PHONE_NOT_NEARBY;
     case EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED:
-      // TODO(tbarzic): When hard lock is enabled change this to
-      // IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_INSTRUCTIONS.
-      return 0;
+      return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_HARDLOCK_INSTRUCTIONS;
+    case EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED:
+      return IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_UNSUPPORTED_ANDROID_VERSION;
     default:
       return 0;
   }
 }
 
+bool TooltipContainsDeviceType(EasyUnlockScreenlockStateHandler::State state) {
+  return state == EasyUnlockScreenlockStateHandler::STATE_AUTHENTICATED ||
+         state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNLOCKABLE ||
+         state == EasyUnlockScreenlockStateHandler::STATE_NO_BLUETOOTH ||
+         state == EasyUnlockScreenlockStateHandler::STATE_PHONE_UNSUPPORTED;
+}
+
 }  // namespace
 
 
@@ -99,10 +112,13 @@
 
   state_ = new_state;
 
-  // If lock screen is not active, just cache the current state.
-  // The screenlock state will get refreshed in |ScreenDidLock|.
-  if (!screenlock_bridge_->IsLocked())
+  // If lock screen is not active or it forces offline password, just cache the
+  // current state. The screenlock state will get refreshed in |ScreenDidLock|.
+  if (!screenlock_bridge_->IsLocked() ||
+      screenlock_bridge_->lock_handler()->GetAuthType(user_email_) ==
+          ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD) {
     return;
+  }
 
   UpdateScreenlockAuthType();
 
@@ -115,7 +131,9 @@
   }
   icon_options.SetIconAsResourceURL(icon_url);
 
-  UpdateTooltipOptions(&icon_options);
+  bool trial_run = IsTrialRun();
+
+  UpdateTooltipOptions(trial_run, &icon_options);
 
   if (UseOpaqueIcon(state_))
     icon_options.SetOpacity(kOpaqueIconOpacity);
@@ -125,6 +143,13 @@
   if (HasAnimation(state_))
     icon_options.SetAnimation(kSpinnerResourceWidth, kSpinnerIntervalMs);
 
+  // Hardlocking is disabled in trial run.
+  if (!trial_run && HardlockOnClick(state_))
+    icon_options.SetHardlockOnClick();
+
+  if (trial_run && state_ == STATE_AUTHENTICATED)
+    MarkTrialRunComplete();
+
   screenlock_bridge_->lock_handler()->ShowUserPodCustomIcon(user_email_,
                                                             icon_options);
 }
@@ -140,16 +165,15 @@
 }
 
 void EasyUnlockScreenlockStateHandler::UpdateTooltipOptions(
+    bool trial_run,
     ScreenlockBridge::UserPodCustomIconOptions* icon_options) {
-  bool show_tutorial = ShouldShowTutorial();
-
   size_t resource_id = 0;
   base::string16 device_name;
-  if (show_tutorial) {
+  if (trial_run && state_ == STATE_AUTHENTICATED) {
     resource_id = IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_TUTORIAL;
   } else {
     resource_id = GetTooltipResourceId(state_);
-    if (state_ == STATE_AUTHENTICATED || state_ == STATE_PHONE_UNLOCKABLE)
+    if (TooltipContainsDeviceType(state_))
       device_name = GetDeviceName();
   }
 
@@ -166,20 +190,17 @@
   if (tooltip.empty())
     return;
 
-  if (show_tutorial)
-    MarkTutorialShown();
-
-  icon_options->SetTooltip(tooltip, show_tutorial /* autoshow tooltip */);
+  icon_options->SetTooltip(
+      tooltip,
+      state_ == STATE_AUTHENTICATED && trial_run /* autoshow tooltip */);
 }
 
-bool EasyUnlockScreenlockStateHandler::ShouldShowTutorial() {
-  if (state_ != STATE_AUTHENTICATED)
-    return false;
+bool EasyUnlockScreenlockStateHandler::IsTrialRun() {
   return pref_service_ &&
          pref_service_->GetBoolean(prefs::kEasyUnlockShowTutorial);
 }
 
-void EasyUnlockScreenlockStateHandler::MarkTutorialShown() {
+void EasyUnlockScreenlockStateHandler::MarkTrialRunComplete() {
   if (!pref_service_)
     return;
   pref_service_->SetBoolean(prefs::kEasyUnlockShowTutorial, false);
@@ -195,6 +216,10 @@
 }
 
 void EasyUnlockScreenlockStateHandler::UpdateScreenlockAuthType() {
+  if (screenlock_bridge_->lock_handler()->GetAuthType(user_email_) ==
+          ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD)
+    return;
+
   if (state_ == STATE_AUTHENTICATED) {
     screenlock_bridge_->lock_handler()->SetAuthType(
         user_email_,
diff --git a/chrome/browser/signin/easy_unlock_screenlock_state_handler.h b/chrome/browser/signin/easy_unlock_screenlock_state_handler.h
index dc5c2cc..452687b 100644
--- a/chrome/browser/signin/easy_unlock_screenlock_state_handler.h
+++ b/chrome/browser/signin/easy_unlock_screenlock_state_handler.h
@@ -38,6 +38,9 @@
     // A phone eligible to unlock the device is found, but it's not close enough
     // to be allowed to unlock the device.
     STATE_PHONE_NOT_NEARBY,
+    // An Easy Unlock enabled phone is found, but it is not allowed to unlock
+    // the device because it does not support reporting it's lock screen state.
+    STATE_PHONE_UNSUPPORTED,
     // The device can be unlocked using Easy Unlock.
     STATE_AUTHENTICATED
   };
@@ -61,17 +64,20 @@
   virtual void OnScreenDidLock() OVERRIDE;
   virtual void OnScreenDidUnlock() OVERRIDE;
 
+  // Updates icon's tooltip options.
+  // |trial_run|: Whether the trial Easy Unlock run is in progress.
   void UpdateTooltipOptions(
+      bool trial_run,
       ScreenlockBridge::UserPodCustomIconOptions* icon_options);
 
-  // Whether the tutorial message should be shown to the user. The message is
-  // shown only once, when the user encounters STATE_AUTHENTICATED for the first
-  // time (across sessions). After the tutorial message is shown,
-  // |MarkTutorialShown| should be called to prevent further tutorial message.
-  bool ShouldShowTutorial();
+  // Whether this is the first, trial Easy Unlock run. If this is the case, a
+  // tutorial message should be shown and hard-locking be disabled in
+  // Authenticated state. The trial run will be active if Easy Unlock never
+  // entered Authenticated state (across sessions).
+  bool IsTrialRun();
 
-  // Sets user preference that prevents showing of tutorial messages.
-  void MarkTutorialShown();
+  // Sets user preference that marks trial run completed.
+  void MarkTrialRunComplete();
 
   // Gets the name to be used for the device. The name depends on the device
   // type (example values: Chromebook and Chromebox).
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index afbb94f..b9240aa 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -131,7 +131,7 @@
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   registry->RegisterBooleanPref(
       prefs::kEasyUnlockShowTutorial,
-      false,
+      true,
       user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
   registry->RegisterDictionaryPref(
       prefs::kEasyUnlockPairing,
@@ -290,7 +290,15 @@
       base::Bind(&EasyUnlockService::OnPrefsChanged, base::Unretained(this)));
   OnPrefsChanged();
 
+#if defined(OS_CHROMEOS)
+  // Only start Bluetooth detection for ChromeOS since the feature is
+  // only offered on ChromeOS. Enabling this on non-ChromeOS platforms
+  // previously introduced a performance regression: http://crbug.com/404482
+  // Make sure not to reintroduce a performance regression if re-enabling on
+  // additional platforms.
+  // TODO(xiyuan): Revisit when non-chromeos platforms are supported.
   bluetooth_detector_->Initialize();
+#endif  // defined(OS_CHROMEOS)
 }
 
 void EasyUnlockService::LoadApp() {
@@ -361,6 +369,9 @@
   ClearRemoteDevices();
   SetTurnOffFlowStatus(IDLE);
 
+  // Make sure lock screen state set by the extension gets reset.
+  screenlock_state_handler_.reset();
+
   if (GetComponentLoader(profile_)->Exists(extension_misc::kEasyUnlockAppId)) {
     extensions::ExtensionSystem* extension_system =
         extensions::ExtensionSystem::Get(profile_);
diff --git a/chrome/browser/signin/screenlock_bridge.cc b/chrome/browser/signin/screenlock_bridge.cc
index 56c2910..4a95429 100644
--- a/chrome/browser/signin/screenlock_bridge.cc
+++ b/chrome/browser/signin/screenlock_bridge.cc
@@ -37,7 +37,8 @@
       animation_resource_width_(0u),
       animation_frame_length_ms_(0u),
       opacity_(100u),
-      autoshow_tooltip_(false) {
+      autoshow_tooltip_(false),
+      hardlock_on_click_(false) {
 }
 
 ScreenlockBridge::UserPodCustomIconOptions::~UserPodCustomIconOptions() {}
@@ -86,6 +87,10 @@
                           animation_frame_length_ms_);
     result->Set("animation", animation);
   }
+
+  if (hardlock_on_click_)
+    result->SetBoolean("hardlockOnClick", true);
+
   return result.Pass();
 }
 
@@ -130,6 +135,10 @@
   autoshow_tooltip_ = autoshow;
 }
 
+void ScreenlockBridge::UserPodCustomIconOptions::SetHardlockOnClick() {
+  hardlock_on_click_ = true;
+}
+
 // static
 std::string ScreenlockBridge::GetAuthenticatedUserEmail(Profile* profile) {
   // |profile| has to be a signed-in profile with SigninManager already
diff --git a/chrome/browser/signin/screenlock_bridge.h b/chrome/browser/signin/screenlock_bridge.h
index 72cec43..5391ca3 100644
--- a/chrome/browser/signin/screenlock_bridge.h
+++ b/chrome/browser/signin/screenlock_bridge.h
@@ -78,6 +78,10 @@
     // shown with the icon.
     void SetTooltip(const base::string16& tooltip, bool autoshow);
 
+    // If hardlock on click is set, clicking the icon in the screenlock will
+    // go to state where password is required for unlock.
+    void SetHardlockOnClick();
+
    private:
     std::string icon_resource_url_;
     scoped_ptr<gfx::Image> icon_image_;
@@ -95,6 +99,8 @@
     base::string16 tooltip_;
     bool autoshow_tooltip_;
 
+    bool hardlock_on_click_;
+
     DISALLOW_COPY_AND_ASSIGN(UserPodCustomIconOptions);
   };
 
@@ -108,6 +114,7 @@
       NUMERIC_PIN = 2,
       USER_CLICK = 3,
       EXPAND_THEN_USER_CLICK = 4,
+      FORCE_OFFLINE_PASSWORD = 5
     };
 
     // Displays |message| in a banner on the lock screen.
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index 955a4b6..0769185 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -761,6 +761,8 @@
   last_get_token_error_ = error;
   switch (error.state()) {
     case GoogleServiceAuthError::CONNECTION_FAILED:
+    case GoogleServiceAuthError::REQUEST_CANCELED:
+    case GoogleServiceAuthError::SERVICE_ERROR:
     case GoogleServiceAuthError::SERVICE_UNAVAILABLE: {
       // Transient error. Retry after some time.
       request_access_token_backoff_.InformOfRequest(false);
@@ -774,7 +776,6 @@
       NotifyObservers();
       break;
     }
-    case GoogleServiceAuthError::SERVICE_ERROR:
     case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: {
       if (!sync_prefs_.SyncHasAuthError()) {
         sync_prefs_.SetSyncAuthError(true);
@@ -785,6 +786,9 @@
       // Fallthrough.
     }
     default: {
+      if (error.state() != GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
+        LOG(ERROR) << "Unexpected persistent error: " << error.ToString();
+      }
       // Show error to user.
       UpdateAuthErrorState(error);
     }
diff --git a/chrome/browser/sync/test/integration/sync_auth_test.cc b/chrome/browser/sync/test/integration/sync_auth_test.cc
index c4bf4e7..71b8c4f 100644
--- a/chrome/browser/sync/test/integration/sync_auth_test.cc
+++ b/chrome/browser/sync/test/integration/sync_auth_test.cc
@@ -206,10 +206,10 @@
             GetSyncService((0))->GetAuthError().state());
 }
 
-// Verify that ProfileSyncService ends up with an SERVICE_ERROR auth error when
+// Verify that ProfileSyncService retries after SERVICE_ERROR auth error when
 // an invalid_client error is returned by OAuth2TokenService with an
 // HTTP_BAD_REQUEST (400) response code.
-IN_PROC_BROWSER_TEST_F(SyncAuthTest, InvalidClient) {
+IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryInvalidClient) {
   ASSERT_TRUE(SetupSync());
   ASSERT_FALSE(AttemptToTriggerAuthError());
   GetFakeServer()->SetUnauthenticated();
@@ -218,13 +218,12 @@
                          net::HTTP_BAD_REQUEST,
                          net::URLRequestStatus::SUCCESS);
   ASSERT_TRUE(AttemptToTriggerAuthError());
-  ASSERT_EQ(GoogleServiceAuthError::SERVICE_ERROR,
-            GetSyncService((0))->GetAuthError().state());
+  ASSERT_TRUE(GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
 }
 
-// Verify that ProfileSyncService ends up with a REQUEST_CANCELED auth error
-// when when OAuth2TokenService has encountered a URLRequestStatus of CANCELED.
-IN_PROC_BROWSER_TEST_F(SyncAuthTest, RequestCanceled) {
+// Verify that ProfileSyncService retries after REQUEST_CANCELED auth error
+// when OAuth2TokenService has encountered a URLRequestStatus of CANCELED.
+IN_PROC_BROWSER_TEST_F(SyncAuthTest, RetryRequestCanceled) {
   ASSERT_TRUE(SetupSync());
   ASSERT_FALSE(AttemptToTriggerAuthError());
   GetFakeServer()->SetUnauthenticated();
@@ -233,8 +232,7 @@
                          net::HTTP_INTERNAL_SERVER_ERROR,
                          net::URLRequestStatus::CANCELED);
   ASSERT_TRUE(AttemptToTriggerAuthError());
-  ASSERT_EQ(GoogleServiceAuthError::REQUEST_CANCELED,
-            GetSyncService((0))->GetAuthError().state());
+  ASSERT_TRUE(GetSyncService((0))->IsRetryingAccessTokenFetchForTest());
 }
 
 // Verify that ProfileSyncService fails initial sync setup during backend
diff --git a/chrome/browser/thumbnails/thumbnail_list_source.cc b/chrome/browser/thumbnails/thumbnail_list_source.cc
index ad47041..bd447c2 100644
--- a/chrome/browser/thumbnails/thumbnail_list_source.cc
+++ b/chrome/browser/thumbnails/thumbnail_list_source.cc
@@ -94,6 +94,11 @@
     int render_process_id,
     int render_frame_id,
     const content::URLDataSource::GotDataCallback& callback) {
+  if (!profile_->GetTopSites()) {
+    callback.Run(NULL);
+    return;
+  }
+
   profile_->GetTopSites()->GetMostVisitedURLs(
       base::Bind(&ThumbnailListSource::OnMostVisitedURLsAvailable,
                  weak_ptr_factory_.GetWeakPtr(),
diff --git a/chrome/browser/ui/autofill/password_generation_popup_controller.h b/chrome/browser/ui/autofill/password_generation_popup_controller.h
index cd912ec..bcd0c9a 100644
--- a/chrome/browser/ui/autofill/password_generation_popup_controller.h
+++ b/chrome/browser/ui/autofill/password_generation_popup_controller.h
@@ -22,6 +22,9 @@
   // Spacing between the border of the popup and any text.
   static const int kHorizontalPadding = 10;
 
+  // Desired height of the password section.
+  static const int kPopupPasswordSectionHeight = 62;
+
   // Called by the view when the saved passwords link is clicked.
   virtual void OnSavedPasswordsLinkClicked() = 0;
 
diff --git a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_bridge.mm
index 6c22cb8..9f4cd9a 100644
--- a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_bridge.mm
+++ b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_bridge.mm
@@ -9,8 +9,7 @@
 #include "base/logging.h"
 #include "chrome/browser/ui/autofill/autofill_popup_controller.h"
 #import "chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h"
-#include "ui/base/cocoa/window_size_constants.h"
-#include "ui/gfx/rect.h"
+#include "ui/gfx/size.h"
 
 namespace autofill {
 
@@ -36,8 +35,7 @@
 }
 
 gfx::Size PasswordGenerationPopupViewBridge::GetPreferredSizeOfPasswordView() {
-  // TODO(gcasto): Implement this function.
-  return gfx::Size();
+  return gfx::Size(NSSizeToCGSize([view_ preferredSize]));
 }
 
 void PasswordGenerationPopupViewBridge::UpdateBoundsAndRedrawPopup() {
@@ -50,8 +48,7 @@
 
 bool PasswordGenerationPopupViewBridge::IsPointInPasswordBounds(
     const gfx::Point& point) {
-  // TODO(gcasto): Implement this function.
-  return true;
+  return [view_ isPointInPasswordBounds:NSPointFromCGPoint(point.ToCGPoint())];
 }
 
 PasswordGenerationPopupView* PasswordGenerationPopupView::Create(
diff --git a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h
index e475161..35dd04f 100644
--- a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h
+++ b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h
@@ -7,6 +7,7 @@
 
 #import <Cocoa/Cocoa.h>
 
+#include "base/mac/scoped_nsobject.h"
 #include "chrome/browser/ui/autofill/password_generation_popup_controller.h"
 #import "chrome/browser/ui/cocoa/autofill/autofill_popup_base_view_cocoa.h"
 
@@ -23,9 +24,12 @@
   // The cross-platform controller for this view.
   __weak autofill::PasswordGenerationPopupController* controller_;
 
-  __weak NSTextField* passwordField_;
-  __weak NSTextField* passwordSubtextField_;
-  __weak HyperlinkTextView* helpTextView_;
+  base::scoped_nsobject<NSView> passwordSection_;
+  base::scoped_nsobject<NSTextField> passwordField_;
+  base::scoped_nsobject<NSTextField> passwordTitleField_;
+  base::scoped_nsobject<NSImageView> keyIcon_;
+  base::scoped_nsobject<NSBox> divider_;
+  base::scoped_nsobject<HyperlinkTextView> helpTextView_;
 }
 
 // Designated initializer.
@@ -33,10 +37,17 @@
     (autofill::PasswordGenerationPopupController*)controller
                    frame:(NSRect)frame;
 
+// Determines whether |point| falls inside the password section of the popup.
+// |point| needs to be in the popup's coordinate system.
+- (BOOL)isPointInPasswordBounds:(NSPoint)point;
+
 // Informs the view that its controller has been (or will imminently be)
 // destroyed.
 - (void)controllerDestroyed;
 
+// The preferred size for the popup.
+- (NSSize)preferredSize;
+
 @end
 
 #endif  // CHROME_BROWSER_UI_COCOA_AUTOFILL_PASSWORD_GENERATION_POPUP_VIEW_COCOA_H_
diff --git a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
index a8a85fd..a3db139 100644
--- a/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
+++ b/chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.mm
@@ -4,6 +4,8 @@
 
 #import "chrome/browser/ui/cocoa/autofill/password_generation_popup_view_cocoa.h"
 
+#include <cmath>
+
 #include "base/logging.h"
 #include "base/strings/sys_string_conversions.h"
 #include "chrome/browser/ui/autofill/autofill_popup_controller.h"
@@ -14,6 +16,7 @@
 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h"
 #import "chrome/browser/ui/cocoa/l10n_util.h"
 #include "components/autofill/core/browser/popup_item_ids.h"
+#include "grit/theme_resources.h"
 #include "skia/ext/skia_utils_mac.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/font_list.h"
@@ -24,11 +27,19 @@
 #include "ui/gfx/text_constants.h"
 
 using autofill::AutofillPopupView;
+using autofill::PasswordGenerationPopupController;
 using autofill::PasswordGenerationPopupView;
 using base::scoped_nsobject;
 
 namespace {
 
+// The height of the divider between the password and help sections, in pixels.
+const CGFloat kDividerHeight = 1;
+
+// The amount of whitespace, in pixels, between lines of text in the password
+// section.
+const CGFloat kPasswordSectionVerticalSeparation = 5;
+
 NSColor* DividerColor() {
   return gfx::SkColorToCalibratedNSColor(
       PasswordGenerationPopupView::kDividerColor);
@@ -65,30 +76,52 @@
   if (self = [super initWithDelegate:controller frame:frame]) {
     controller_ = controller;
 
-    passwordField_ = [self textFieldWithText:controller_->password()
-                                       color:[self nameColor]
-                                   alignment:NSLeftTextAlignment];
-    [self addSubview:passwordField_];
+    passwordSection_.reset([[NSView alloc] initWithFrame:NSZeroRect]);
+    [self addSubview:passwordSection_];
 
-    passwordSubtextField_ = [self textFieldWithText:controller_->SuggestedText()
-                                              color:[self subtextColor]
-                                          alignment:NSRightTextAlignment];
-    [self addSubview:passwordSubtextField_];
+    passwordField_.reset(
+        [[self textFieldWithText:controller_->password()
+                      attributes:[self passwordAttributes]] retain]);
+    [passwordSection_ addSubview:passwordField_];
 
-    scoped_nsobject<HyperlinkTextView> helpTextView(
-        [[HyperlinkTextView alloc] initWithFrame:NSZeroRect]);
-    [helpTextView setMessage:base::SysUTF16ToNSString(controller_->HelpText())
-                    withFont:[self textFont]
-                messageColor:HelpTextColor()];
-    [helpTextView addLinkRange:controller_->HelpTextLinkRange().ToNSRange()
-                      withName:@""
-                     linkColor:HelpLinkColor()];
-    [helpTextView setDelegate:self];
-    [[helpTextView textContainer] setLineFragmentPadding:0.0f];
-    [helpTextView setVerticallyResizable:YES];
-    [self addSubview:helpTextView];
-    helpTextView_ = helpTextView.get();
-  }
+    passwordTitleField_.reset(
+        [[self textFieldWithText:controller_->SuggestedText()
+                      attributes:[self passwordTitleAttributes]] retain]);
+    [passwordSection_ addSubview:passwordTitleField_];
+
+    keyIcon_.reset([[NSImageView alloc] initWithFrame:NSZeroRect]);
+    NSImage* keyImage = ResourceBundle::GetSharedInstance()
+        .GetImageNamed(IDR_GENERATE_PASSWORD_KEY)
+        .ToNSImage();
+    [keyIcon_ setImage:keyImage];
+    [passwordSection_ addSubview:keyIcon_];
+
+    divider_.reset([[NSBox alloc] initWithFrame:NSZeroRect]);
+    [divider_ setBoxType:NSBoxCustom];
+    [divider_ setBorderType:NSLineBorder];
+    [divider_ setBorderColor:DividerColor()];
+    [self addSubview:divider_];
+
+    helpTextView_.reset([[HyperlinkTextView alloc] initWithFrame:NSZeroRect]);
+    [helpTextView_ setMessage:base::SysUTF16ToNSString(controller_->HelpText())
+                     withFont:[self textFont]
+                 messageColor:HelpTextColor()];
+    [helpTextView_ addLinkRange:controller_->HelpTextLinkRange().ToNSRange()
+                       withName:@""
+                      linkColor:HelpLinkColor()];
+    [helpTextView_ setDelegate:self];
+    [helpTextView_ setDrawsBackground:YES];
+    [helpTextView_ setBackgroundColor:HelpTextBackgroundColor()];
+    [helpTextView_
+        setTextContainerInset:NSMakeSize(controller_->kHorizontalPadding,
+                                         controller_->kHelpVerticalPadding)];
+    // Remove the underlining.
+    NSTextStorage* text = [helpTextView_ textStorage];
+    [text addAttribute:NSUnderlineStyleAttributeName
+                 value:@(NSUnderlineStyleNone)
+                 range:controller_->HelpTextLinkRange().ToNSRange()];
+    [self addSubview:helpTextView_];
+}
 
   return