Merge from Chromium at DEPS revision 40.0.2214.38
This commit was generated by merge_to_master.py.
Change-Id: I5e881388509cd5fb3882f4ba2ef6663965219173
diff --git a/DEPS b/DEPS
index a896bfb..96d5aef 100644
--- a/DEPS
+++ b/DEPS
@@ -68,7 +68,7 @@
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling PDFium
# and whatever else without interference from each other.
- 'pdfium_revision': '4dc95e74e1acc75f4eab08bc771874cd2a9c3a9b',
+ 'pdfium_revision': '0e46ce2948c8b45e9e5adcf6c4cb27620d5ba8ae',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling openmax_dl
# and whatever else without interference from each other.
diff --git a/android_webview/android_webview_jarjar_content_resources.target.darwin-arm.mk b/android_webview/android_webview_jarjar_content_resources.target.darwin-arm.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.darwin-arm.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.darwin-arm.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.darwin-arm64.mk b/android_webview/android_webview_jarjar_content_resources.target.darwin-arm64.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.darwin-arm64.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.darwin-arm64.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.darwin-mips.mk b/android_webview/android_webview_jarjar_content_resources.target.darwin-mips.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.darwin-mips.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.darwin-mips.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.darwin-mips64.mk b/android_webview/android_webview_jarjar_content_resources.target.darwin-mips64.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.darwin-mips64.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.darwin-mips64.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.darwin-x86.mk b/android_webview/android_webview_jarjar_content_resources.target.darwin-x86.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.darwin-x86.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.darwin-x86.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.darwin-x86_64.mk b/android_webview/android_webview_jarjar_content_resources.target.darwin-x86_64.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.darwin-x86_64.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.darwin-x86_64.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.linux-arm.mk b/android_webview/android_webview_jarjar_content_resources.target.linux-arm.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.linux-arm.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.linux-arm.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.linux-arm64.mk b/android_webview/android_webview_jarjar_content_resources.target.linux-arm64.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.linux-arm64.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.linux-arm64.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.linux-mips.mk b/android_webview/android_webview_jarjar_content_resources.target.linux-mips.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.linux-mips.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.linux-mips.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.linux-mips64.mk b/android_webview/android_webview_jarjar_content_resources.target.linux-mips64.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.linux-mips64.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.linux-mips64.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.linux-x86.mk b/android_webview/android_webview_jarjar_content_resources.target.linux-x86.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.linux-x86.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.linux-x86.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/android_webview_jarjar_content_resources.target.linux-x86_64.mk b/android_webview/android_webview_jarjar_content_resources.target.linux-x86_64.mk
index 7118a65..0607057 100644
--- a/android_webview/android_webview_jarjar_content_resources.target.linux-x86_64.mk
+++ b/android_webview/android_webview_jarjar_content_resources.target.linux-x86_64.mk
@@ -19,7 +19,7 @@
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp: $(LOCAL_PATH)/build/android/gyp/util/build_utils.py $(LOCAL_PATH)/build/android/gyp/jarjar_resources.py $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-hdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-mdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/bubble_arrow_up.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/ondemand_overlay.9.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_search_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/ic_menu_share_holo_light.png $(LOCAL_PATH)/content/public/android/java/res/drawable-xxxhdpi/pageinfo_warning_major.png $(LOCAL_PATH)/content/public/android/java/res/layout/validation_message_bubble.xml $(LOCAL_PATH)/content/public/android/java/res/menu/select_action_menu.xml $(LOCAL_PATH)/content/public/android/java/res/values-v17/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values-v21/styles.xml $(LOCAL_PATH)/content/public/android/java/res/values/attrs.xml $(LOCAL_PATH)/content/public/android/java/res/values/dimens.xml $(LOCAL_PATH)/content/public/android/java/res/values/strings.xml $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Copying and jar-jaring resources for android_webview_jarjar_content_resources ($@)"
$(hide)cd $(gyp_local_path)/android_webview; mkdir -p $(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources; python ../build/android/gyp/jarjar_resources.py --input-dir ../content/public/android/java/res --output-dir "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_res" --rules-path ../android_webview/build/jarjar-rules.txt --stamp "$(gyp_shared_intermediate_dir)/android_webview_jarjar_content_resources/jarjar_resources.stamp"
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index b29821b..0c8546a 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -364,6 +364,7 @@
void AwContentBrowserClient::SelectClientCertificate(
int render_process_id,
int render_frame_id,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) {
AwContentsClientBridgeBase* client =
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h
index 9bd6f03..7ae700d 100644
--- a/android_webview/browser/aw_content_browser_client.h
+++ b/android_webview/browser/aw_content_browser_client.h
@@ -106,6 +106,7 @@
virtual void SelectClientCertificate(
int render_process_id,
int render_frame_id,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) override;
virtual blink::WebNotificationPermission
diff --git a/android_webview/common/aw_crash_handler.cc b/android_webview/common/aw_crash_handler.cc
index a637298..fbd4285 100644
--- a/android_webview/common/aw_crash_handler.cc
+++ b/android_webview/common/aw_crash_handler.cc
@@ -6,6 +6,9 @@
#include <android/log.h>
#include <signal.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+#include <unistd.h>
#include "base/logging.h"
@@ -27,6 +30,14 @@
if (g_crash_msg_ptr != NULL)
__android_log_write(ANDROID_LOG_ERROR, "chromium", g_crash_msg_ptr);
+ // Detect if some buggy code in the embedder did reinstall the handler using
+ // signal() instead of sigaction() (which would cause |info| to be invalid).
+ struct sigaction cur_handler;
+ if (sigaction(sig, NULL, &cur_handler) != 0 ||
+ (cur_handler.sa_flags & SA_SIGINFO) == 0) {
+ info = NULL;
+ }
+
// We served our purpose. Now restore the old crash handlers. If the embedder
// did register a custom crash handler, it will be invoked by the kernel after
// this function returns. Otherwise, this will end up invoking the default
@@ -36,6 +47,17 @@
signal(kExceptionSignals[i], SIG_DFL);
}
}
+
+ if ((info != NULL && info->si_pid) || sig == SIGABRT) {
+ // This signal was triggered by somebody sending us the signal with kill().
+ // In order to retrigger it, we have to queue a new signal by calling
+ // kill() ourselves. The special case (si_pid == 0 && sig == SIGABRT) is
+ // due to the kernel sending a SIGABRT from a user request via SysRQ.
+ if (syscall(__NR_tgkill, getpid(), syscall(__NR_gettid), sig) < 0) {
+ // If we failed to kill ourselves resort to terminating uncleanly.
+ exit(1);
+ }
+ }
}
} // namespace
@@ -65,6 +87,7 @@
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
+ // Mask all exception signals when we're handling one of them.
for (uint32_t i = 0; i < arraysize(kExceptionSignals); ++i)
sigaddset(&sa.sa_mask, kExceptionSignals[i]);
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 7f0dc03..d1fd6ce 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -811,8 +811,9 @@
long nativeWebContents = nativeGetWebContents(mNativeAwContents);
- mWindowAndroid = mContext instanceof Activity
- ? new ActivityWindowAndroid((Activity) mContext)
+ Activity activity = ContentViewCore.activityFromContext(mContext);
+ mWindowAndroid = activity != null
+ ? new ActivityWindowAndroid(activity)
: new WindowAndroid(mContext.getApplicationContext());
mContentViewCore = createAndInitializeContentViewCore(
mContainerView, mContext, mInternalAccessAdapter, nativeWebContents,
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
index 253a361..e39252f 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwJavaBridgeTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwJavaBridgeTest.java
@@ -43,9 +43,9 @@
}
});
// Destroying one AwContents from within the JS callback should still
- // leave others functioning.
- loadDataSync(view2.getAwContents(), client2.getOnPageFinishedHelper(),
- html, "text/html", false);
+ // leave others functioning. Note that we must do this asynchronously,
+ // as Blink thread is currently blocked waiting for this method to finish.
+ loadDataAsync(view2.getAwContents(), html, "text/html", false);
} catch (Throwable t) {
throw new RuntimeException(t);
}
@@ -66,9 +66,99 @@
// Ensure the JS interface object is there, and invoke the test method.
assertEquals("\"function\"", executeJavaScriptAndWaitForResult(
awContents, mContentsClient, "typeof test.destroy"));
+ int currentCallCount = client2.getOnPageFinishedHelper().getCallCount();
awContents.evaluateJavaScript("test.destroy()", null);
- client2.getOnPageFinishedHelper().waitForCallback(
- client2.getOnPageFinishedHelper().getCallCount());
+ client2.getOnPageFinishedHelper().waitForCallback(currentCallCount);
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView", "Android-JavaBridge"})
+ public void testTwoWebViewsCreatedSimultaneously() throws Throwable {
+ final AwContents awContents1 = mTestContainerView.getAwContents();
+ final TestAwContentsClient client2 = new TestAwContentsClient();
+ final AwTestContainerView view2 = createAwTestContainerViewOnMainSync(client2);
+ final AwContents awContents2 = view2.getAwContents();
+
+ enableJavaScriptOnUiThread(awContents1);
+ enableJavaScriptOnUiThread(awContents2);
+
+ class Test {
+ Test(int value) {
+ mValue = value;
+ }
+ @JavascriptInterface
+ public int getValue() {
+ return mValue;
+ }
+ private int mValue;
+ }
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ awContents1.addPossiblyUnsafeJavascriptInterface(new Test(1), "test", null);
+ awContents2.addPossiblyUnsafeJavascriptInterface(new Test(2), "test", null);
+ }
+ });
+ final String html = "<html>Hello World</html>";
+ loadDataSync(awContents1, mContentsClient.getOnPageFinishedHelper(), html,
+ "text/html", false);
+ loadDataSync(awContents2, client2.getOnPageFinishedHelper(), html,
+ "text/html", false);
+
+ assertEquals("1",
+ executeJavaScriptAndWaitForResult(awContents1, mContentsClient, "test.getValue()"));
+ assertEquals("2",
+ executeJavaScriptAndWaitForResult(awContents2, client2, "test.getValue()"));
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView", "Android-JavaBridge"})
+ public void testTwoWebViewsSecondCreatedAfterLoadingInFirst() throws Throwable {
+ final AwContents awContents1 = mTestContainerView.getAwContents();
+ enableJavaScriptOnUiThread(awContents1);
+
+ class Test {
+ Test(int value) {
+ mValue = value;
+ }
+ @JavascriptInterface
+ public int getValue() {
+ return mValue;
+ }
+ private int mValue;
+ }
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ awContents1.addPossiblyUnsafeJavascriptInterface(new Test(1), "test", null);
+ }
+ });
+ final String html = "<html>Hello World</html>";
+ loadDataSync(awContents1, mContentsClient.getOnPageFinishedHelper(), html,
+ "text/html", false);
+ assertEquals("1",
+ executeJavaScriptAndWaitForResult(awContents1, mContentsClient, "test.getValue()"));
+
+ final TestAwContentsClient client2 = new TestAwContentsClient();
+ final AwTestContainerView view2 = createAwTestContainerViewOnMainSync(client2);
+ final AwContents awContents2 = view2.getAwContents();
+ enableJavaScriptOnUiThread(awContents2);
+
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ awContents2.addPossiblyUnsafeJavascriptInterface(new Test(2), "test", null);
+ }
+ });
+ loadDataSync(awContents2, client2.getOnPageFinishedHelper(), html,
+ "text/html", false);
+
+ assertEquals("1",
+ executeJavaScriptAndWaitForResult(awContents1, mContentsClient, "test.getValue()"));
+ assertEquals("2",
+ executeJavaScriptAndWaitForResult(awContents2, client2, "test.getValue()"));
}
}
diff --git a/build/android/setup.gyp b/build/android/setup.gyp
index f10ab3e..7dce19d 100644
--- a/build/android/setup.gyp
+++ b/build/android/setup.gyp
@@ -12,26 +12,13 @@
# <(SHARED_LIB_DIR)
'target_name': 'copy_system_libraries',
'type': 'none',
- 'conditions': [
- ['target_arch=="arm" and arm_thumb==1', {
- 'copies': [
- {
- 'destination': '<(SHARED_LIB_DIR)/',
- 'files': [
- '<(android_stlport_libs_dir)/thumb/libstlport_shared.so',
- ],
- },
+ 'copies': [
+ {
+ 'destination': '<(SHARED_LIB_DIR)/',
+ 'files': [
+ '<(android_stlport_libs_dir)/libstlport_shared.so',
],
- }, {
- 'copies': [
- {
- 'destination': '<(SHARED_LIB_DIR)/',
- 'files': [
- '<(android_stlport_libs_dir)/libstlport_shared.so',
- ],
- },
- ],
- }],
+ },
],
},
],
diff --git a/build/common.gypi b/build/common.gypi
index 256515a..7ec5ae2 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -2295,6 +2295,11 @@
'arm_thumb%': 1,
}],
+ # Set default compiler flags depending on MIPS architecture variant.
+ ['target_arch=="mipsel" and mips_arch_variant=="r2" and android_webview_build==0', {
+ 'mips_fpu_mode%': 'fp32',
+ }],
+
['android_webview_build==1', {
# The WebView build gets its cpu-specific flags from the Android build system.
'arm_arch%': '',
@@ -2302,6 +2307,7 @@
'arm_fpu%': '',
'arm_float_abi%': '',
'arm_thumb%': 0,
+ 'mips_fpu_mode%': '',
}],
# Enable brlapi by default for chromeos.
@@ -2359,7 +2365,6 @@
}, {
'use_seccomp_bpf%': 0,
}],
-
# Set component build with LTO until all tests pass.
# This also reduces link time.
['use_lto==1', {
@@ -2398,7 +2403,7 @@
# Whether to allow building of the GPU-related isolates.
'archive_gpu_tests%': 0,
- # Whether to allow building of chromoting related isolates.
+ # Whether to allow building of chromoting related isolates.
'archive_chromoting_tests%': 0,
},
'target_defaults': {
@@ -4660,19 +4665,10 @@
'--sysroot=<(android_ndk_sysroot)',
'-nostdlib',
],
- 'variables': {
- 'conditions': [
- ['target_arch=="arm" and arm_thumb==1', {
- 'thumb_option%': '-mthumb',
- }, {
- 'thumb_option%': '',
- }],
- ],
- },
'libraries': [
'-l<(android_stlport_library)',
# Manually link the libgcc.a that the cross compiler uses.
- '<!(<(android_toolchain)/*-gcc <(thumb_option) -print-libgcc-file-name)',
+ '<!(<(android_toolchain)/*-gcc -print-libgcc-file-name)',
'-lc',
'-ldl',
'-lm',
@@ -4737,12 +4733,8 @@
'cflags': [
'-isystem<(android_stlport_include)',
],
- 'conditions': [
- ['target_arch=="arm" and arm_thumb==1', {
- 'ldflags': [ '-L<(android_stlport_libs_dir)/thumb' ]
- }, {
- 'ldflags': [ '-L<(android_stlport_libs_dir)' ]
- }],
+ 'ldflags': [
+ '-L<(android_stlport_libs_dir)',
],
}, { # else: android_webview_build!=0
'aosp_build_settings': {
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index ce9a175..409bba9 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -37,23 +37,6 @@
android_chrome_build_id = "\"\""
}
- # ABI ------------------------------------------------------------------------
-
- if (cpu_arch == "x86") {
- android_app_abi = "x86"
- } else if (cpu_arch == "arm") {
- import("//build/config/arm.gni")
- if (arm_version < 7) {
- android_app_abi = "armeabi"
- } else {
- android_app_abi = "armeabi-v7a"
- }
- } else if (cpu_arch == "mipsel") {
- android_app_abi = "mips"
- } else {
- assert(false, "Unknown Android ABI: " + cpu_arch)
- }
-
# Host stuff -----------------------------------------------------------------
# Defines the name the Android build gives to the current host CPU
@@ -123,13 +106,8 @@
android_prebuilt_arch = "android-arm"
_binary_prefix = "arm-linux-androideabi"
android_toolchain_root = "$arm_android_toolchain_root"
- if (arm_use_thumb) {
- android_libgcc_file =
- "$android_toolchain_root/lib/gcc/arm-linux-androideabi/${_android_toolchain_version}/thumb/libgcc.a"
- } else {
- android_libgcc_file =
+ android_libgcc_file =
"$android_toolchain_root/lib/gcc/arm-linux-androideabi/${_android_toolchain_version}/libgcc.a"
- }
} else if (cpu_arch == "mipsel") {
android_prebuilt_arch = "android-mips"
_binary_prefix = "mipsel-linux-android"
@@ -152,6 +130,23 @@
} else {
android_stlport_library = "stlport_static"
}
+
+ # ABI ------------------------------------------------------------------------
+
+ if (cpu_arch == "x86") {
+ android_app_abi = "x86"
+ } else if (cpu_arch == "arm") {
+ import("//build/config/arm.gni")
+ if (arm_version < 7) {
+ android_app_abi = "armeabi"
+ } else {
+ android_app_abi = "armeabi-v7a"
+ }
+ } else if (cpu_arch == "mipsel") {
+ android_app_abi = "mips"
+ } else {
+ assert(false, "Unknown Android ABI: " + cpu_arch)
+ }
} else {
if (!defined(is_android_webview_build)) {
is_android_webview_build = false
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 3d1b341..ac73fb6 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -481,15 +481,9 @@
# caution.
android_stlport_root = "$android_ndk_root/sources/cxx-stl/stlport"
- cflags += [
- "-isystem" + rebase_path("$android_stlport_root/stlport",
- root_build_dir)
- ]
- if (arm_use_thumb) {
- lib_dirs += [ "$android_stlport_root/libs/$android_app_abi/thumb" ]
- } else {
- lib_dirs += [ "$android_stlport_root/libs/$android_app_abi" ]
- }
+ cflags += [ "-isystem" +
+ rebase_path("$android_stlport_root/stlport", root_build_dir) ]
+ lib_dirs += [ "$android_stlport_root/libs/$android_app_abi" ]
if (component_mode == "shared_library") {
libs += [ "stlport_shared" ]
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
index be6e68b..a18bf98 100644
--- a/build/util/LASTCHANGE
+++ b/build/util/LASTCHANGE
@@ -1 +1 @@
-LASTCHANGE=472e9e85cdec
+LASTCHANGE=07329508ba1d
diff --git a/build/util/LASTCHANGE.blink b/build/util/LASTCHANGE.blink
index 730df68..0266d2a 100644
--- a/build/util/LASTCHANGE.blink
+++ b/build/util/LASTCHANGE.blink
@@ -1 +1 @@
-LASTCHANGE=186261
+LASTCHANGE=186783
diff --git a/cc/base/rolling_time_delta_history.cc b/cc/base/rolling_time_delta_history.cc
index 0f95cc5..db04f58 100644
--- a/cc/base/rolling_time_delta_history.cc
+++ b/cc/base/rolling_time_delta_history.cc
@@ -26,10 +26,6 @@
chronological_sample_deque_.push_back(it);
}
-size_t RollingTimeDeltaHistory::SampleCount() {
- return sample_set_.size();
-}
-
void RollingTimeDeltaHistory::Clear() {
chronological_sample_deque_.clear();
sample_set_.clear();
diff --git a/cc/base/rolling_time_delta_history.h b/cc/base/rolling_time_delta_history.h
index 603c813..e51fb86 100644
--- a/cc/base/rolling_time_delta_history.h
+++ b/cc/base/rolling_time_delta_history.h
@@ -23,8 +23,6 @@
void InsertSample(base::TimeDelta time);
- size_t SampleCount();
-
void Clear();
// Returns the smallest sample that is greater than or equal to the specified
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 822fcf3..d43dd02 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -1101,8 +1101,12 @@
if (maximum_scale) {
gfx::Size bounds_at_maximum_scale = gfx::ToCeiledSize(
gfx::ScaleSize(pile_->tiling_size(), maximum_scale));
- if (bounds_at_maximum_scale.GetArea() <=
- layer_tree_impl()->device_viewport_size().GetArea())
+ int64 maximum_area = static_cast<int64>(bounds_at_maximum_scale.width()) *
+ static_cast<int64>(bounds_at_maximum_scale.height());
+ gfx::Size viewport = layer_tree_impl()->device_viewport_size();
+ int64 viewport_area = static_cast<int64>(viewport.width()) *
+ static_cast<int64>(viewport.height());
+ if (maximum_area <= viewport_area)
can_raster_at_maximum_scale = true;
}
// Use the computed scales for the raster scale directly, do not try to use
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 4b42eca..b75aa63 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -1872,6 +1872,9 @@
TEST_F(PictureLayerImplTest, HighResRequiredWhenUnsharedActiveAllReady) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// No tiles shared.
@@ -1893,6 +1896,9 @@
TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// All tiles shared (no invalidation).
@@ -1917,6 +1923,9 @@
TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfShared) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
CreateHighLowResAndSetAllTilesVisible();
@@ -1991,6 +2000,9 @@
TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
@@ -3136,6 +3148,8 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// Make sure some tiles are not shared.
@@ -3163,6 +3177,8 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// Make sure some tiles are not shared.
@@ -3186,6 +3202,8 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// Make sure some tiles are not shared.
@@ -3210,6 +3228,8 @@
gfx::Size tile_size(100, 100);
gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
// Make sure some tiles are not shared.
@@ -3297,6 +3317,9 @@
TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfShared) {
gfx::Size layer_bounds(400, 400);
gfx::Size tile_size(100, 100);
+
+ host_impl_.SetViewportSize(layer_bounds);
+
SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size);
CreateHighLowResAndSetAllTilesVisible();
@@ -3658,6 +3681,8 @@
gfx::Size tile_size(400, 400);
gfx::Size layer_bounds(1000, 2000);
+ host_impl_.SetViewportSize(layer_bounds);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
scoped_refptr<FakePicturePileImpl> active_pile =
diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc
index 9c814be..e0676d2 100644
--- a/cc/layers/tiled_layer_unittest.cc
+++ b/cc/layers/tiled_layer_unittest.cc
@@ -260,6 +260,8 @@
};
TEST_F(TiledLayerTest, PushDirtyTiles) {
+ layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
+
scoped_refptr<FakeTiledLayer> layer =
make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
scoped_ptr<FakeTiledLayerImpl> layer_impl =
@@ -289,6 +291,8 @@
}
TEST_F(TiledLayerTest, Scale) {
+ layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
+
layer_tree_host_->SetDeviceScaleFactor(1.5);
scoped_refptr<FakeTiledLayer> layer =
@@ -351,6 +355,8 @@
}
TEST_F(TiledLayerTest, PushDeletedTiles) {
+ layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
+
scoped_refptr<FakeTiledLayer> layer =
make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
scoped_ptr<FakeTiledLayerImpl> layer_impl =
@@ -1200,6 +1206,8 @@
}
TEST_F(TiledLayerTest, TilesPaintedWithoutOcclusion) {
+ layer_tree_host_->SetViewportSize(gfx::Size(1000, 1000));
+
scoped_refptr<FakeTiledLayer> layer =
make_scoped_refptr(new FakeTiledLayer(resource_manager_.get()));
RenderSurfaceLayerList render_surface_layer_list;
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index a472475..214b989 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -99,6 +99,8 @@
switch (mode) {
case SkXfermode::kSrcOver_Mode:
return BlendModeNormal;
+ case SkXfermode::kScreen_Mode:
+ return BlendModeScreen;
case SkXfermode::kOverlay_Mode:
return BlendModeOverlay;
case SkXfermode::kDarken_Mode:
@@ -129,7 +131,7 @@
return BlendModeLuminosity;
default:
NOTREACHED();
- return BlendModeNormal;
+ return BlendModeNone;
}
}
@@ -866,99 +868,8 @@
return background_with_filters;
}
-scoped_ptr<ScopedResource>
-GLRenderer::ApplyInverseTransformForBackgroundFilters(
- DrawingFrame* frame,
- const RenderPassDrawQuad* quad,
- const gfx::Transform& contents_device_transform,
- skia::RefPtr<SkImage> filtered_device_background,
- const gfx::Rect& backdrop_bounding_rect) {
- // This method draws a background filter, which applies a filter to any pixels
- // behind the quad and seen through its background. The algorithm works as
- // follows:
- // 1. Read the pixels in the bounding box into a buffer.
- // Moved to GLRenderer::GetBackdropBoundingBoxForRenderPassQuad().
- // 2. Read the pixels in the bounding box into a buffer R.
- // Moved to GLRenderer::GetBackdropTexture().
- // 3. Apply the background filter to R, so that it is applied in the pixels'
- // coordinate space. Moved to GLRenderer::ApplyBackgroundFilters().
- // 4. Apply the quad's inverse transform to map the pixels in R into the
- // quad's content space. This implicitly clips R by the content bounds of the
- // quad since the destination texture has bounds matching the quad's content.
- // 5. Draw the background texture for the contents using the same transform as
- // used to draw the contents itself. This is done without blending to replace
- // the current background pixels with the new filtered background.
- // 6. Draw the contents of the quad over drop of the new background with
- // blending, as per usual. The filtered background pixels will show through
- // any non-opaque pixels in this draws.
- //
- // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5.
-
- // TODO(danakj): When this algorithm changes, update
- // LayerTreeHost::PrioritizeTextures() accordingly.
-
- DCHECK(filtered_device_background);
-
- GrTexture* texture = filtered_device_background->getTexture();
-
- scoped_ptr<ScopedResource> background_texture =
- ScopedResource::Create(resource_provider_);
- background_texture->Allocate(
- quad->rect.size(),
- ResourceProvider::TextureHintImmutableFramebuffer,
- RGBA_8888);
-
- const RenderPass* target_render_pass = frame->current_render_pass;
- bool using_background_texture =
- UseScopedTexture(frame, background_texture.get(), quad->rect);
-
- if (using_background_texture) {
- // Copy the readback pixels from device to the background texture for the
- // surface.
-
- gfx::Transform contents_device_transform_inverse(
- gfx::Transform::kSkipInitialization);
- bool did_invert = contents_device_transform.GetInverse(
- &contents_device_transform_inverse);
- DCHECK(did_invert);
- gfx::Transform device_to_framebuffer_transform;
- QuadRectTransform(
- &device_to_framebuffer_transform, gfx::Transform(), quad->rect);
- device_to_framebuffer_transform.PreconcatTransform(
- contents_device_transform_inverse);
-
-#ifndef NDEBUG
- GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
- gl_->Clear(GL_COLOR_BUFFER_BIT);
-#endif
-
- // The background_texture is oriented the same as the frame buffer.
- // The transform we are copying with has a vertical flip, as well as
- // the |device_to_framebuffer_transform|, which cancel each other out. So do
- // not flip the contents in the shader to maintain orientation.
- bool flip_vertically = false;
-
- CopyTextureToFramebuffer(frame,
- texture->getTextureHandle(),
- backdrop_bounding_rect,
- device_to_framebuffer_transform,
- flip_vertically);
- }
-
- UseRenderPass(frame, target_render_pass);
-
- if (!using_background_texture)
- return nullptr;
- return background_texture.Pass();
-}
-
void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
const RenderPassDrawQuad* quad) {
- SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
- SetBlendEnabled(
- CanApplyBlendModeUsingBlendFunc(blend_mode) &&
- (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
-
ScopedResource* contents_texture =
render_pass_textures_.get(quad->render_pass_id);
if (!contents_texture || !contents_texture->id())
@@ -984,62 +895,59 @@
SetupQuadForAntialiasing(contents_device_transform, quad,
&surface_quad, edge);
- bool need_background_texture = !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
- ShouldApplyBackgroundFilters(frame, quad);
+ SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
+ bool use_shaders_for_blending =
+ !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
+ ShouldApplyBackgroundFilters(frame, quad) ||
+ settings_->force_blending_with_shaders;
scoped_ptr<ScopedResource> background_texture;
skia::RefPtr<SkImage> background_image;
gfx::Rect background_rect;
- if (need_background_texture) {
+ if (use_shaders_for_blending) {
// Compute a bounding box around the pixels that will be visible through
// the quad.
background_rect = GetBackdropBoundingBoxForRenderPassQuad(
frame, quad, contents_device_transform, use_aa);
- }
- if (!background_rect.IsEmpty()) {
- // The pixels from the filtered background should completely replace the
- // current pixel values.
- bool disable_blending = blend_enabled();
- if (disable_blending)
- SetBlendEnabled(false);
+ if (!background_rect.IsEmpty()) {
+ // The pixels from the filtered background should completely replace the
+ // current pixel values.
+ if (blend_enabled())
+ SetBlendEnabled(false);
- // Read the pixels in the bounding box into a buffer R.
- scoped_ptr<ScopedResource> scoped_background_texture =
- GetBackdropTexture(background_rect);
+ // Read the pixels in the bounding box into a buffer R.
+ // This function allocates a texture, which should contribute to the
+ // amount of memory used by render surfaces:
+ // LayerTreeHost::CalculateMemoryForRenderSurfaces.
+ background_texture = GetBackdropTexture(background_rect);
- skia::RefPtr<SkImage> background_with_filters;
- if (ShouldApplyBackgroundFilters(frame, quad) &&
- scoped_background_texture) {
- // Apply the background filters to R, so that it is applied in the pixels'
- // coordinate space.
- background_with_filters =
- ApplyBackgroundFilters(frame, quad, scoped_background_texture.get());
- }
-
- if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
- background_with_filters) {
- // The background with filters will be copied to the frame buffer.
- // Apply the quad's inverse transform to map the pixels in R into the
- // quad's content space. This implicitly clips R by the content bounds of
- // the quad since the destination texture has bounds matching the quad's
- // content.
- background_texture = ApplyInverseTransformForBackgroundFilters(
- frame, quad, contents_device_transform, background_with_filters,
- background_rect);
- } else if (!CanApplyBlendModeUsingBlendFunc(blend_mode)) {
- if (background_with_filters) {
- // The background with filters will be used as backdrop for blending.
- background_image = background_with_filters;
- } else {
- background_texture = scoped_background_texture.Pass();
+ if (ShouldApplyBackgroundFilters(frame, quad) && background_texture) {
+ // Apply the background filters to R, so that it is applied in the
+ // pixels' coordinate space.
+ background_image =
+ ApplyBackgroundFilters(frame, quad, background_texture.get());
}
}
- if (disable_blending)
- SetBlendEnabled(true);
+ if (!background_texture) {
+ // Something went wrong with reading the backdrop.
+ DCHECK(!background_image);
+ use_shaders_for_blending = false;
+ } else if (background_image) {
+ background_texture.reset();
+ } else if (CanApplyBlendModeUsingBlendFunc(blend_mode) &&
+ ShouldApplyBackgroundFilters(frame, quad)) {
+ // Something went wrong with applying background filters to the backdrop.
+ use_shaders_for_blending = false;
+ background_texture.reset();
+ }
}
+ SetBlendEnabled(
+ !use_shaders_for_blending &&
+ (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
+
// TODO(senorblanco): Cache this value so that we don't have to do it for both
// the surface and its replica. Apply filters to the contents texture.
skia::RefPtr<SkImage> filter_image;
@@ -1072,25 +980,6 @@
}
}
- if (background_texture && ShouldApplyBackgroundFilters(frame, quad)) {
- // Draw the background texture if it has some filters applied.
- DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode));
- DCHECK(background_texture->size() == quad->rect.size());
- ResourceProvider::ScopedReadLockGL lock(resource_provider_,
- background_texture->id());
-
- // The background_texture is oriented the same as the frame buffer. The
- // transform we are copying with has a vertical flip, so flip the contents
- // in the shader to maintain orientation
- bool flip_vertically = true;
-
- CopyTextureToFramebuffer(frame,
- lock.texture_id(),
- quad->rect,
- quad->quadTransform(),
- flip_vertically);
- }
-
scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock;
unsigned mask_texture_id = 0;
SamplerType mask_sampler = SamplerTypeNA;
@@ -1101,9 +990,6 @@
mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target());
}
- // TODO(danakj): use the background_texture and blend the background in with
- // this draw instead of having a separate copy of the background texture.
-
scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock;
if (filter_image) {
GrTexture* texture = filter_image->getTexture();
@@ -1117,7 +1003,7 @@
contents_resource_lock->target());
}
- if (CanApplyBlendModeUsingBlendFunc(blend_mode)) {
+ if (!use_shaders_for_blending) {
if (!use_blend_equation_advanced_coherent_ && use_blend_equation_advanced_)
GLC(gl_, gl_->BlendBarrierKHR());
@@ -1144,10 +1030,10 @@
int shader_backdrop_location = -1;
int shader_backdrop_rect_location = -1;
- BlendMode shader_blend_mode = ((background_texture || background_image) &&
- !CanApplyBlendModeUsingBlendFunc(blend_mode))
+ DCHECK_EQ(background_texture || background_image, use_shaders_for_blending);
+ BlendMode shader_blend_mode = use_shaders_for_blending
? BlendModeFromSkXfermode(blend_mode)
- : BlendModeNormal;
+ : BlendModeNone;
if (use_aa && mask_texture_id && !use_color_matrix) {
const RenderPassMaskProgramAA* program = GetRenderPassMaskProgramAA(
@@ -1424,7 +1310,7 @@
if (filter_image)
GLC(gl_, gl_->Flush());
- if (CanApplyBlendModeUsingBlendFunc(blend_mode))
+ if (!use_shaders_for_blending)
RestoreBlendFuncToDefault(blend_mode);
}
@@ -2452,43 +2338,6 @@
GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
}
-void GLRenderer::CopyTextureToFramebuffer(const DrawingFrame* frame,
- int texture_id,
- const gfx::Rect& rect,
- const gfx::Transform& draw_matrix,
- bool flip_vertically) {
- TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
- gl_, &highp_threshold_cache_, highp_threshold_min_, rect.bottom_right());
-
- const RenderPassProgram* program =
- GetRenderPassProgram(tex_coord_precision, BlendModeNormal);
- SetUseProgram(program->program());
-
- GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
-
- if (flip_vertically) {
- GLC(gl_,
- gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
- 0.f,
- 1.f,
- 1.f,
- -1.f));
- } else {
- GLC(gl_,
- gl_->Uniform4f(program->vertex_shader().tex_transform_location(),
- 0.f,
- 0.f,
- 1.f,
- 1.f));
- }
-
- SetShaderOpacity(1.f, program->fragment_shader().alpha_location());
- DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
- GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
- DrawQuadGeometry(
- frame, draw_matrix, rect, program->vertex_shader().matrix_location());
-}
-
void GLRenderer::Finish() {
TRACE_EVENT0("cc", "GLRenderer::Finish");
GLC(gl_, gl_->Finish());
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index 4930204..ecadebb 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -167,12 +167,6 @@
DrawingFrame* frame,
const RenderPassDrawQuad* quad,
ScopedResource* background_texture);
- scoped_ptr<ScopedResource> ApplyInverseTransformForBackgroundFilters(
- DrawingFrame* frame,
- const RenderPassDrawQuad* quad,
- const gfx::Transform& contents_device_transform,
- skia::RefPtr<SkImage> backdrop_bitmap,
- const gfx::Rect& backdrop_bounding_rect);
void DrawRenderPassQuad(DrawingFrame* frame, const RenderPassDrawQuad* quad);
void DrawSolidColorQuad(const DrawingFrame* frame,
@@ -208,12 +202,6 @@
int matrix_location);
void SetUseProgram(unsigned program);
- void CopyTextureToFramebuffer(const DrawingFrame* frame,
- int texture_id,
- const gfx::Rect& rect,
- const gfx::Transform& draw_matrix,
- bool flip_vertically);
-
bool UseScopedTexture(DrawingFrame* frame,
const ScopedResource* resource,
const gfx::Rect& viewport_rect);
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index dc68675..2af953e 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -57,8 +57,11 @@
static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
switch (blend_mode) {
+ case BlendModeNone:
case BlendModeNormal:
return SkXfermode::kSrcOver_Mode;
+ case BlendModeScreen:
+ return SkXfermode::kScreen_Mode;
case BlendModeOverlay:
return SkXfermode::kOverlay_Mode;
case BlendModeDarken:
@@ -1421,6 +1424,7 @@
for (int i = 0; i < NumBlendModes; ++i) {
BlendMode blend_mode = static_cast<BlendMode>(i);
SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
+ settings_.force_blending_with_shaders = (blend_mode != BlendModeNone);
// RenderPassProgram
render_passes_in_draw_order_.clear();
child_pass = AddRenderPass(&render_passes_in_draw_order_,
@@ -1690,7 +1694,7 @@
// If use_aa incorrectly ignores clipping, it will use the
// RenderPassProgramAA shader instead of the RenderPassProgram.
- TestRenderPassProgram(TexCoordPrecisionMedium, BlendModeNormal);
+ TestRenderPassProgram(TexCoordPrecisionMedium, BlendModeNone);
}
TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
diff --git a/cc/output/program_binding.h b/cc/output/program_binding.h
index 722c782..a10d0ab 100644
--- a/cc/output/program_binding.h
+++ b/cc/output/program_binding.h
@@ -59,7 +59,7 @@
void Initialize(ContextProvider* context_provider,
TexCoordPrecision precision,
SamplerType sampler,
- BlendMode blend_mode = BlendModeNormal) {
+ BlendMode blend_mode = BlendModeNone) {
DCHECK(context_provider);
DCHECK(!initialized_);
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index b962d4a..e22e446 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -669,9 +669,9 @@
}
#define BLEND_MODE_UNIFORMS "s_backdropTexture", "backdropRect"
-#define UNUSED_BLEND_MODE_UNIFORMS (is_default_blend_mode() ? 2 : 0)
+#define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 2 : 0)
#define BLEND_MODE_SET_LOCATIONS(X, POS) \
- if (!is_default_blend_mode()) { \
+ if (has_blend_mode()) { \
DCHECK_LT(static_cast<size_t>(POS) + 1, arraysize(X)); \
backdrop_location_ = locations[POS]; \
backdrop_rect_location_ = locations[POS + 1]; \
@@ -680,7 +680,7 @@
FragmentTexBlendMode::FragmentTexBlendMode()
: backdrop_location_(-1),
backdrop_rect_location_(-1),
- blend_mode_(BlendModeNormal) {
+ blend_mode_(BlendModeNone) {
}
std::string FragmentTexBlendMode::SetBlendModeFunctions(
@@ -688,7 +688,7 @@
if (shader_string.find("ApplyBlendMode") == std::string::npos)
return shader_string;
- if (is_default_blend_mode()) {
+ if (!has_blend_mode()) {
return "#define ApplyBlendMode(X) (X)\n" + shader_string;
}
@@ -902,6 +902,10 @@
std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
switch (blend_mode_) {
+ case BlendModeNormal:
+ return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
+ case BlendModeScreen:
+ return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
case BlendModeLighten:
return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
" (1.0 - dst.a) * src.rgb + dst.rgb);";
@@ -963,11 +967,11 @@
" srcDstAlpha.a,"
" srcDstAlpha.rgb);"
"result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
- default:
+ case BlendModeNone:
+ case NumBlendModes:
NOTREACHED();
- // simple alpha compositing
- return "result.rgb = src.rgb * src.a + dst.rgb * dst.a * (1 - src.a)";
}
+ return "result = vec4(1.0, 0.0, 0.0, 1.0);";
}
FragmentTexAlphaBinding::FragmentTexAlphaBinding()
diff --git a/cc/output/shader.h b/cc/output/shader.h
index 0384366..8c1f264 100644
--- a/cc/output/shader.h
+++ b/cc/output/shader.h
@@ -39,7 +39,9 @@
};
enum BlendMode {
+ BlendModeNone,
BlendModeNormal,
+ BlendModeScreen,
BlendModeOverlay,
BlendModeDarken,
BlendModeLighten,
@@ -305,7 +307,7 @@
BlendMode blend_mode() const { return blend_mode_; }
void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; }
- bool is_default_blend_mode() const { return blend_mode_ == BlendModeNormal; }
+ bool has_blend_mode() const { return blend_mode_ != BlendModeNone; }
protected:
FragmentTexBlendMode();
diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc
index 2f0735c..cd5e890 100644
--- a/cc/resources/tile_manager_unittest.cc
+++ b/cc/resources/tile_manager_unittest.cc
@@ -149,7 +149,9 @@
};
TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueue) {
- SetupDefaultTrees(gfx::Size(1000, 1000));
+ const gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+ SetupDefaultTrees(layer_bounds);
active_layer_->CreateDefaultTilingsAndTiles();
pending_layer_->CreateDefaultTilingsAndTiles();
@@ -391,7 +393,9 @@
}
TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueue) {
- SetupDefaultTrees(gfx::Size(1000, 1000));
+ const gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+ SetupDefaultTrees(layer_bounds);
active_layer_->CreateDefaultTilingsAndTiles();
pending_layer_->CreateDefaultTilingsAndTiles();
@@ -560,6 +564,8 @@
gfx::Size tile_size(102, 102);
gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+
scoped_refptr<FakePicturePileImpl> pending_pile =
FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds);
SetupPendingTree(pending_pile);
@@ -670,7 +676,9 @@
}
TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) {
- SetupDefaultTrees(gfx::Size(1000, 1000));
+ const gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+ SetupDefaultTrees(layer_bounds);
active_layer_->CreateDefaultTilingsAndTiles();
pending_layer_->CreateDefaultTilingsAndTiles();
@@ -717,7 +725,9 @@
}
TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) {
- SetupDefaultTrees(gfx::Size(1000, 1000));
+ const gfx::Size layer_bounds(1000, 1000);
+ host_impl_.SetViewportSize(layer_bounds);
+ SetupDefaultTrees(layer_bounds);
active_layer_->CreateDefaultTilingsAndTiles();
pending_layer_->CreateDefaultTilingsAndTiles();
diff --git a/cc/test/data/background_filter_blur_off_axis.png b/cc/test/data/background_filter_blur_off_axis.png
index 050ec54..5077171 100644
--- a/cc/test/data/background_filter_blur_off_axis.png
+++ b/cc/test/data/background_filter_blur_off_axis.png
Binary files differ
diff --git a/cc/test/data/background_filter_blur_outsets.png b/cc/test/data/background_filter_blur_outsets.png
index 9234496..3293ab8 100644
--- a/cc/test/data/background_filter_blur_outsets.png
+++ b/cc/test/data/background_filter_blur_outsets.png
Binary files differ
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index af7eb5b..ae85fc7 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -960,7 +960,6 @@
size_t LayerTreeHost::CalculateMemoryForRenderSurfaces(
const RenderSurfaceLayerList& update_list) {
size_t readback_bytes = 0;
- size_t max_background_texture_bytes = 0;
size_t contents_texture_bytes = 0;
// Start iteration at 1 to skip the root surface as it does not have a texture
@@ -974,17 +973,16 @@
RGBA_8888);
contents_texture_bytes += bytes;
- if (render_surface_layer->background_filters().IsEmpty())
+ if (render_surface_layer->background_filters().IsEmpty() &&
+ render_surface_layer->uses_default_blend_mode())
continue;
- if (bytes > max_background_texture_bytes)
- max_background_texture_bytes = bytes;
if (!readback_bytes) {
readback_bytes = Resource::MemorySizeBytes(device_viewport_size_,
RGBA_8888);
}
}
- return readback_bytes + max_background_texture_bytes + contents_texture_bytes;
+ return readback_bytes + contents_texture_bytes;
}
void LayerTreeHost::PaintMasksForRenderSurface(Layer* render_surface_layer,
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc
index fd15b52..eb90012 100644
--- a/cc/trees/layer_tree_host_common.cc
+++ b/cc/trees/layer_tree_host_common.cc
@@ -392,7 +392,7 @@
gfx::Rect visible_rect_in_target_surface_space =
layer->drawable_content_rect();
- if (!layer->render_target()->render_surface()->clip_rect().IsEmpty()) {
+ if (layer->render_target()->render_surface()->is_clipped()) {
// The |layer| L has a target T which owns a surface Ts. The surface Ts
// has a target TsT.
//
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index e0436ba..d4ded78 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -2791,6 +2791,56 @@
}
TEST_F(LayerTreeHostCommonTest,
+ VisibleContentRectsForClippedSurfaceWithEmptyClip) {
+ scoped_refptr<Layer> root = Layer::Create();
+ scoped_refptr<LayerWithForcedDrawsContent> child1 =
+ make_scoped_refptr(new LayerWithForcedDrawsContent());
+ scoped_refptr<LayerWithForcedDrawsContent> child2 =
+ make_scoped_refptr(new LayerWithForcedDrawsContent());
+ scoped_refptr<LayerWithForcedDrawsContent> child3 =
+ make_scoped_refptr(new LayerWithForcedDrawsContent());
+ root->AddChild(child1);
+ root->AddChild(child2);
+ root->AddChild(child3);
+
+ scoped_ptr<FakeLayerTreeHost> host(CreateFakeLayerTreeHost());
+ host->SetRootLayer(root);
+
+ gfx::Transform identity_matrix;
+ SetLayerPropertiesForTesting(root.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false);
+ SetLayerPropertiesForTesting(child1.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(5.f, 5.f), gfx::Size(50, 50), true,
+ false);
+ SetLayerPropertiesForTesting(child2.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(75.f, 75.f), gfx::Size(50, 50), true,
+ false);
+ SetLayerPropertiesForTesting(child3.get(), identity_matrix, gfx::Point3F(),
+ gfx::PointF(125.f, 125.f), gfx::Size(50, 50),
+ true, false);
+
+ RenderSurfaceLayerList render_surface_layer_list;
+ // Now set the root render surface an empty clip.
+ LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
+ root.get(), gfx::Size(), &render_surface_layer_list);
+
+ LayerTreeHostCommon::CalculateDrawProperties(&inputs);
+ ASSERT_TRUE(root->render_surface());
+ EXPECT_FALSE(root->is_clipped());
+
+ gfx::Rect empty;
+ EXPECT_EQ(empty, root->render_surface()->clip_rect());
+ EXPECT_TRUE(root->render_surface()->is_clipped());
+
+ // Visible content rect calculation will check if the target surface is
+ // clipped or not. An empty clip rect does not indicate the render surface
+ // is unclipped.
+ EXPECT_EQ(empty, child1->visible_content_rect());
+ EXPECT_EQ(empty, child2->visible_content_rect());
+ EXPECT_EQ(empty, child3->visible_content_rect());
+}
+
+TEST_F(LayerTreeHostCommonTest,
DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) {
scoped_refptr<Layer> root = Layer::Create();
scoped_refptr<LayerWithForcedDrawsContent> child =
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 9bee07e..e2cb1e9 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -2738,10 +2738,16 @@
}
did_lock_scrolling_layer_ = true;
- if (!allow_bubbling_for_current_layer) {
+
+ // When scrolls are allowed to bubble, it's important that the original
+ // scrolling layer be preserved. This ensures that, after a scroll bubbles,
+ // the user can reverse scroll directions and immediately resume scrolling
+ // the original layer that scrolled.
+ if (!should_bubble_scrolls_)
active_tree_->SetCurrentlyScrollingLayer(layer_impl);
+
+ if (!allow_bubbling_for_current_layer)
break;
- }
if (allow_unrestricted_bubbling_for_current_layer) {
pending_delta -= applied_delta;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index adc11d0..7c0f8ab 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -7530,6 +7530,56 @@
}
}
+TEST_F(LayerTreeHostImplVirtualViewportTest,
+ TouchFlingCanLockToViewportLayerAfterBubbling) {
+ gfx::Size content_size = gfx::Size(100, 160);
+ gfx::Size outer_viewport = gfx::Size(50, 80);
+ gfx::Size inner_viewport = gfx::Size(25, 40);
+
+ SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport);
+
+ LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer();
+ LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer();
+
+ scoped_ptr<LayerImpl> child =
+ CreateScrollableLayer(10, outer_viewport, outer_scroll);
+ LayerImpl* child_scroll = child.get();
+ outer_scroll->children()[0]->AddChild(child.Pass());
+
+ DrawFrame();
+ {
+ scoped_ptr<ScrollAndScaleSet> scroll_info;
+
+ gfx::Vector2d scroll_delta(0, inner_viewport.height());
+ EXPECT_EQ(InputHandler::ScrollStarted,
+ host_impl_->ScrollBegin(gfx::Point(), InputHandler::Gesture));
+ EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
+
+ // The child should have scrolled up to its limit.
+ scroll_info = host_impl_->ProcessScrollDeltas();
+ ASSERT_EQ(1u, scroll_info->scrolls.size());
+ ExpectContains(*scroll_info, child_scroll->id(), scroll_delta);
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_scroll);
+
+ // The first |ScrollBy| after the fling should re-lock the scrolling
+ // layer to the first layer that scrolled, the inner viewport scroll layer.
+ EXPECT_EQ(InputHandler::ScrollStarted, host_impl_->FlingScrollBegin());
+ EXPECT_TRUE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
+
+ // The inner viewport should have scrolled up to its limit.
+ scroll_info = host_impl_->ProcessScrollDeltas();
+ ASSERT_EQ(2u, scroll_info->scrolls.size());
+ ExpectContains(*scroll_info, child_scroll->id(), scroll_delta);
+ ExpectContains(*scroll_info, inner_scroll->id(), scroll_delta);
+
+ // As the locked layer is at its limit, no further scrolling can occur.
+ EXPECT_FALSE(host_impl_->ScrollBy(gfx::Point(), scroll_delta).did_scroll);
+ EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll);
+ host_impl_->ScrollEnd();
+ }
+}
+
class LayerTreeHostImplWithImplicitLimitsTest : public LayerTreeHostImplTest {
public:
virtual void SetUp() override {
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index 7a9ef21..9b971a8b 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -52,15 +52,18 @@
const uint32 kUseMasks = 1 << 0;
const uint32 kUseAntialiasing = 1 << 1;
const uint32 kUseColorMatrix = 1 << 2;
+const uint32 kForceShaders = 1 << 3;
class LayerTreeHostBlendingPixelTest : public LayerTreePixelTest {
public:
- LayerTreeHostBlendingPixelTest() {
+ LayerTreeHostBlendingPixelTest()
+ : force_antialiasing_(false), force_blending_with_shaders_(false) {
pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
}
virtual void InitializeSettings(LayerTreeSettings* settings) override {
settings->force_antialiasing = force_antialiasing_;
+ settings->force_blending_with_shaders = force_blending_with_shaders_;
}
protected:
@@ -230,6 +233,7 @@
this->impl_side_painting_ = false;
this->force_antialiasing_ = (flags & kUseAntialiasing);
+ this->force_blending_with_shaders_ = (flags & kForceShaders);
if ((flags & kUseAntialiasing) && (type == PIXEL_TEST_GL)) {
// Anti aliasing causes differences up to 7 pixels at the edges.
@@ -279,7 +283,8 @@
RunPixelTest(type, root, base::FilePath(expected_path));
}
- bool force_antialiasing_ = false;
+ bool force_antialiasing_;
+ bool force_blending_with_shaders_;
};
TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
@@ -433,6 +438,61 @@
kUseMasks | kUseAntialiasing | kUseColorMatrix);
}
+// Tests for render passes forcing shaders for all the blend modes.
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kUseAntialiasing | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMask_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskAA_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseAntialiasing | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersColorMatrix_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersColorMatrixAA_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass.png"),
+ kUseAntialiasing | kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
+ RunBlendingWithRenderPass(PIXEL_TEST_GL,
+ FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseColorMatrix | kForceShaders);
+}
+
+TEST_F(LayerTreeHostBlendingPixelTest,
+ BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
+ RunBlendingWithRenderPass(
+ PIXEL_TEST_GL, FILE_PATH_LITERAL("blending_render_pass_mask.png"),
+ kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
+}
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc
index 40fa2c3..a425eed 100644
--- a/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -136,8 +136,8 @@
blur->SetBackgroundFilters(filters);
#if defined(OS_WIN)
- // Windows has 153 pixels off by at most 2: crbug.com/225027
- float percentage_pixels_large_error = 0.3825f; // 153px / (200*200)
+ // Windows has 116 pixels off by at most 2: crbug.com/225027
+ float percentage_pixels_large_error = 0.3f; // 116px / (200*200), rounded up
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
int large_error_allowed = 2;
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 1d5cf1b..c9763a5 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -16,6 +16,7 @@
: impl_side_painting(false),
allow_antialiasing(true),
force_antialiasing(false),
+ force_blending_with_shaders(false),
throttle_frame_production(true),
single_thread_proxy_scheduler(true),
begin_frame_scheduling_enabled(false),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 74a3b0c..c5f08e9 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -21,6 +21,7 @@
bool impl_side_painting;
bool allow_antialiasing;
bool force_antialiasing;
+ bool force_blending_with_shaders;
bool throttle_frame_production;
bool single_thread_proxy_scheduler;
bool begin_frame_scheduling_enabled;
diff --git a/chrome/VERSION b/chrome/VERSION
index c703e46..54500b6 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
MAJOR=40
MINOR=0
BUILD=2214
-PATCH=27
+PATCH=38
diff --git a/chrome/android/java/res/color/button_tint_menu.xml b/chrome/android/java/res/color/blue_mode_tint.xml
similarity index 82%
rename from chrome/android/java/res/color/button_tint_menu.xml
rename to chrome/android/java/res/color/blue_mode_tint.xml
index b8e7fa2..b918ba4 100644
--- a/chrome/android/java/res/color/button_tint_menu.xml
+++ b/chrome/android/java/res/color/blue_mode_tint.xml
@@ -4,5 +4,5 @@
found in the LICENSE file.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@color/default_active_button_color"/>
+ <item android:color="@color/light_active_color"/>
</selector>
diff --git a/chrome/android/java/res/color/dark_mode_tint.xml b/chrome/android/java/res/color/dark_mode_tint.xml
new file mode 100644
index 0000000..28f2282
--- /dev/null
+++ b/chrome/android/java/res/color/dark_mode_tint.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:color="@color/light_active_color" />
+ <item android:state_focused="true" android:color="@color/light_active_color" />
+ <item android:state_pressed="true" android:color="@color/light_active_color" />
+ <item android:state_enabled="false" android:color="#335a5a5a" />
+ <item android:color="@color/light_normal_color"/>
+</selector>
diff --git a/chrome/android/java/res/color/default_button_tint.xml b/chrome/android/java/res/color/default_button_tint.xml
deleted file mode 100644
index c64c121..0000000
--- a/chrome/android/java/res/color/default_button_tint.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_selected="true" android:color="@color/default_active_button_color" />
- <item android:state_focused="true" android:color="@color/default_active_button_color" />
- <item android:state_pressed="true" android:color="@color/default_active_button_color" />
- <item android:state_enabled="false" android:color="#335a5a5a" />
- <item android:color="@color/default_normal_button_color"/>
-</selector>
diff --git a/chrome/android/java/res/color/button_tint_white.xml b/chrome/android/java/res/color/light_mode_tint.xml
similarity index 100%
rename from chrome/android/java/res/color/button_tint_white.xml
rename to chrome/android/java/res/color/light_mode_tint.xml
diff --git a/chrome/android/java/res/layout/spinner.xml b/chrome/android/java/res/layout/spinner.xml
new file mode 100644
index 0000000..988e422
--- /dev/null
+++ b/chrome/android/java/res/layout/spinner.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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. -->
+
+<!-- A plain old Spinner.
+
+ Why is this needed? Because spinners must be inflated from a resource for the AppCompat theme
+ to work. Simply calling new Spinner() will result in a missing spinner arrow on pre-L devices.
+
+ See the FAQ on this page:
+ http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html -->
+<Spinner />
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml
index dc76982..f914ea5 100644
--- a/chrome/android/java/res/values/colors.xml
+++ b/chrome/android/java/res/values/colors.xml
@@ -7,8 +7,8 @@
<resources>
<!-- Common colors -->
<color name="default_text_color">#333</color>
- <color name="default_normal_button_color">#5A5A5A</color>
- <color name="default_active_button_color">#4285F4</color>
+ <color name="light_normal_color">#5A5A5A</color>
+ <color name="light_active_color">#4285F4</color>
<!-- Infobar colors -->
<color name="infobar_background">#fff</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
index 9bf78d4..bb1bbb5 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
@@ -320,7 +320,7 @@
button.setImageDrawable(item.getIcon());
item.getIcon().setLevel(currentLevel);
if (item.isChecked()) {
- button.setTint(button.getResources().getColorStateList(R.color.button_tint_menu));
+ button.setTint(button.getResources().getColorStateList(R.color.blue_mode_tint));
}
button.setEnabled(item.isEnabled());
button.setFocusable(item.isEnabled());
@@ -336,7 +336,7 @@
private void setupMenuButton(TintedImageButton button) {
button.setImageResource(R.drawable.btn_menu);
- button.setTint(button.getResources().getColorStateList(R.color.button_tint_menu));
+ button.setTint(button.getResources().getColorStateList(R.color.blue_mode_tint));
button.setContentDescription(button.getResources().getString(R.string.menu_dismiss_btn));
button.setEnabled(true);
button.setFocusable(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java
index 7848fa5..77b19ea 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AnimationHelper.java
@@ -14,8 +14,10 @@
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.LinearLayout;
+import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.chrome.R;
import java.util.ArrayList;
@@ -220,10 +222,13 @@
mTargetWrapperView.finishTransition();
mContainer.finishTransition();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && mToShow != null &&
- (mAnimationType == ANIMATION_TYPE_SHOW ||
- mAnimationType == ANIMATION_TYPE_SWAP)) {
- mToShow.announceForAccessibility(mInfoBar.getMessage());
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && mToShow != null
+ && (mAnimationType == ANIMATION_TYPE_SHOW
+ || mAnimationType == ANIMATION_TYPE_SWAP)) {
+ TextView messageView = (TextView) mToShow.findViewById(R.id.infobar_message);
+ if (messageView != null) {
+ mToShow.announceForAccessibility(messageView.getText());
+ }
}
}
});
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java
index 4162f73..f16c2f0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/GeneratedPasswordSavedInfoBar.java
@@ -13,6 +13,7 @@
* An infobar to notify that the generated password was saved.
*/
public class GeneratedPasswordSavedInfoBar extends InfoBar {
+ private final String mMessageText;
private final int mInlineLinkRangeStart;
private final int mInlineLinkRangeEnd;
private final String mButtonLabel;
@@ -28,8 +29,9 @@
*/
public GeneratedPasswordSavedInfoBar(long nativeInfoBar, int iconDrawableId, String messageText,
int inlineLinkRangeStart, int inlineLinkRangeEnd, String buttonLabel) {
- super(null, iconDrawableId, messageText);
+ super(null, iconDrawableId, null);
setNativeInfoBar(nativeInfoBar);
+ mMessageText = messageText;
mInlineLinkRangeStart = inlineLinkRangeStart;
mInlineLinkRangeEnd = inlineLinkRangeEnd;
mButtonLabel = buttonLabel;
@@ -43,7 +45,7 @@
@Override
public void createContent(InfoBarLayout layout) {
layout.setButtons(mButtonLabel, null);
- SpannableString message = new SpannableString(getMessage());
+ SpannableString message = new SpannableString(mMessageText);
message.setSpan(
new ClickableSpan() {
@Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java
index 829332b..36f4aad 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBar.java
@@ -73,13 +73,6 @@
}
/**
- * @return The message shown in the infobar, useful for accessibility.
- */
- public CharSequence getMessage() {
- return mMessage;
- }
-
- /**
* Stores a pointer to the native-side counterpart of this InfoBar.
* @param nativeInfoBarPtr Pointer to the NativeInfoBar.
*/
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
index fb48247..77e8cb7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/TranslateLanguagePanel.java
@@ -9,6 +9,7 @@
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
+import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -103,8 +104,9 @@
mTargetAdapter.measureWidthRequiredForView();
// Create the spinners.
- mSourceSpinner = new Spinner(context);
- mTargetSpinner = new Spinner(context);
+ LayoutInflater inflater = LayoutInflater.from(context);
+ mSourceSpinner = (Spinner) inflater.inflate(R.layout.spinner, null);
+ mTargetSpinner = (Spinner) inflater.inflate(R.layout.spinner, null);
mSourceSpinner.setOnItemSelectedListener(this);
mTargetSpinner.setOnItemSelectedListener(this);
mSourceSpinner.setAdapter(mSourceAdapter);
@@ -234,8 +236,9 @@
public View getView(int position, View convertView, ViewGroup parent) {
TextView result;
if (!(convertView instanceof TextView)) {
- result = (TextView) LayoutInflater.from(getContext()).inflate(
- R.layout.infobar_text, null);
+ result = new TextView(getContext());
+ result.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getContext().getResources().getDimension(R.dimen.infobar_text_size));
} else {
result = (TextView) convertView;
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java
index aca80fd..934967c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/TintedDrawable.java
@@ -25,7 +25,7 @@
public TintedDrawable(Resources res, Bitmap bitmap) {
super(res, bitmap);
- mTint = res.getColorStateList(R.color.default_button_tint);
+ mTint = res.getColorStateList(R.color.dark_mode_tint);
}
@Override
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
index aced1b2..558629e 100644
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -184,8 +184,8 @@
Close
</message>
<!-- TranslateInfoBar -->
- <message name="IDS_TRANSLATE_INFOBAR_TEXT" desc="Text to display on the translate infobar to offer a translate. [CHAR-LIMIT=64]">
- This page is in <ph name="SOURCE_LANGUAGE">^1<ex>English</ex></ph>. Translate it to <ph name="TARGET_LANGUAGE">^2<ex>FRENCH</ex></ph>?
+ <message name="IDS_TRANSLATE_INFOBAR_TEXT" meaning="Android" desc="Text to display on the translate infobar to offer a translate. [CHAR-LIMIT=64]">
+ This page is in <ph name="SOURCE_LANGUAGE">^1<ex>English</ex></ph>. Translate it to <ph name="TARGET_LANGUAGE">^2<ex>French</ex></ph>?
</message>
<message name="IDS_TRANSLATE_INFOBAR_CHANGE_LANGUAGES" desc="link text to offer to change languages.">
Change languages
diff --git a/chrome/android/shell/res/values-v17/styles.xml b/chrome/android/shell/res/values-v17/styles.xml
index 3d4da09..755aeff 100644
--- a/chrome/android/shell/res/values-v17/styles.xml
+++ b/chrome/android/shell/res/values-v17/styles.xml
@@ -20,7 +20,7 @@
<item name="colorPrimaryDark">@color/material_deep_teal_500</item>
<!-- Default TintedImageButton tint -->
- <item name="tint">@color/default_button_tint</item>
+ <item name="tint">@color/dark_mode_tint</item>
</style>
</resources>
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 359d75e..80dc7fa 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -91,11 +91,11 @@
<message name="IDS_FLAGS_ENABLE_VIDEO_PLAYER_CHROMECAST_SUPPORT_DESCRIPTION" desc="Description of the about:flag option to the enable the chromecast support for video app.">
This option enables experimental Chromecast support for Video Player app on ChromeOS.
</message>
- <message name="IDS_FLAGS_DISABLE_NEW_ZIP_UNPACKER_NAME" desc="Name of about::flags option to enable the new ZIP unpacker based on the File System Provider API.">
- Enable the new ZIP unpacker.
+ <message name="IDS_FLAGS_DISABLE_NEW_ZIP_UNPACKER_NAME" desc="Name of about::flags option to disable the new ZIP unpacker based on the File System Provider API.">
+ Disable the new ZIP unpacker.
</message>
- <message name="IDS_FLAGS_DISABLE_NEW_ZIP_UNPACKER_DESCRIPTION" desc="Description of about::flags option to enable the new ZIP unpacker based on the File System Provider API.">
- Enable the new ZIP unpacker flow, based on the File System Provider API.
+ <message name="IDS_FLAGS_DISABLE_NEW_ZIP_UNPACKER_DESCRIPTION" desc="Description of about::flags option to disable the new ZIP unpacker based on the File System Provider API.">
+ Disable the new ZIP unpacker flow, based on the File System Provider API.
</message>
<message name="IDS_FILE_SYSTEM_PROVIDER_UNRESPONSIVE_WARNING" desc="A warning shown in a notification that an operation is taking longer than expected.">
An operation is taking longer than expected. Do you want to abort it?
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index fd4a367..cd9c710 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6742,7 +6742,14 @@
<message name="IDS_FLAGS_ENABLE_EASY_UNLOCK_PROXIMITY_DETECTION_DESCRIPTION" desc="Description for the flag that enables Smart Lock to require close proximity between the phone and the Chromebook in order to unlock the Chromebook.">
Enables a Smart Lock setting that restricts unlocking to only work when your phone is very close to (roughly, within an arm's length of) the Chrome device.
</message>
-
+ <if expr="toolkit_views">
+ <message name="IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_NAME" desc="Title for the flag to enable the Link Disambiguation Popup, a bubble that appears over the web content screen when the user uses a touchscreen to touch a link but accidentally touches more than one link in a single gesture. The bubble appears with a zoomed-in view of the area around their touch, allowing them to more easily select the element they wanted.">
+ Enable Link Disambiguation Popup.
+ </message>
+ <message name="IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_DESCRIPTION" desc="Description for the flag to enable the Link Disambiguation Popup, a feature on touchscreens that when enabled will cause a small zoomed popup to appear over a group of links the user has touched, allowing for selection of links on pages not yet optimized for touch input.">
+ Enable the zoomed bubble that appears on touchscreens when accidentally touching more than one link at a time.
+ </message>
+ </if>
<!-- Crashes -->
<message name="IDS_CRASHES_TITLE" desc="Title for the chrome://crashes page.">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6f7cd2d..b5eda1d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -941,7 +941,7 @@
IDS_FLAGS_DISABLE_EASY_SIGNIN_NAME,
IDS_FLAGS_DISABLE_EASY_SIGNIN_DESCRIPTION,
kOsCrOSOwnerOnly,
- SINGLE_VALUE_TYPE(chromeos::switches::kDisableEasySignin),
+ SINGLE_VALUE_TYPE(proximity_auth::switches::kDisableEasySignin),
},
{
"enable-easy-unlock-proximity-detection",
@@ -1647,6 +1647,13 @@
kOsCrOS | kOsWin | kOsLinux,
SINGLE_VALUE_TYPE(views::switches::kDisableViewsRectBasedTargeting)
},
+ {
+ "enable-link-disambiguation-popup",
+ IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_NAME,
+ IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_DESCRIPTION,
+ kOsCrOS | kOsWin,
+ SINGLE_VALUE_TYPE(switches::kEnableLinkDisambiguationPopup)
+ },
#endif
#if defined(ENABLE_EXTENSIONS)
{
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 66ccc01..aa49609 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1755,14 +1755,14 @@
void ChromeContentBrowserClient::SelectClientCertificate(
int render_process_id,
int render_frame_id,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) {
content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
render_process_id, render_frame_id);
WebContents* tab = WebContents::FromRenderFrameHost(rfh);
if (!tab) {
- // TODO(davidben): This makes the request hang, but returning no certificate
- // also breaks. It should abort the request. See https://crbug.com/417092
+ NOTREACHED();
return;
}
@@ -1808,7 +1808,8 @@
}
}
- chrome::ShowSSLClientCertificateSelector(tab, cert_request_info, callback);
+ chrome::ShowSSLClientCertificateSelector(tab, network_session,
+ cert_request_info, callback);
}
void ChromeContentBrowserClient::AddCertificate(
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 93a22cc..c4fe7a6 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -172,6 +172,7 @@
void SelectClientCertificate(
int render_process_id,
int render_frame_id,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) override;
void AddCertificate(net::CertificateMimeType cert_type,
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
index 21ce2ef..984d131 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl.cc
@@ -1097,19 +1097,21 @@
scoped_refptr<InputMethodManager::State> InputMethodManagerImpl::CreateNewState(
Profile* profile) {
StateImpl* new_state = new StateImpl(this, profile);
-#if defined(USE_ATHENA)
- // Athena for now doesn't have user preferences for input methods,
- // therefore no one sets the active input methods in IMF. So just set
- // the default IME here.
- // TODO(shuchen): we need to better initialize with user preferences.
+
+ // Active IM should be set to owner's default.
+ PrefService* prefs = g_browser_process->local_state();
+ const std::string initial_input_method_id =
+ prefs->GetString(chromeos::language_prefs::kPreferredKeyboardLayout);
+
const InputMethodDescriptor* descriptor =
GetInputMethodUtil()->GetInputMethodDescriptorFromId(
- GetInputMethodUtil()->GetFallbackInputMethodDescriptor().id());
+ initial_input_method_id.empty()
+ ? GetInputMethodUtil()->GetFallbackInputMethodDescriptor().id()
+ : initial_input_method_id);
if (descriptor) {
new_state->active_input_method_ids.push_back(descriptor->id());
new_state->current_input_method = *descriptor;
}
-#endif
return scoped_refptr<InputMethodManager::State>(new_state);
}
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
index 498a0c1..f8e553f 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
@@ -168,6 +168,8 @@
mock_delegate_->set_ime_list(ime_list_);
scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(mock_delegate_);
+ // CreateNewState(NULL) returns state with non-empty current_input_method.
+ // So SetState() triggers ChangeInputMethod().
manager_->SetState(manager_->CreateNewState(NULL));
std::vector<std::string> layouts;
@@ -366,12 +368,13 @@
manager_->GetActiveIMEState()->EnableLoginLayouts("en-US", keyboard_layouts);
EXPECT_EQ(5U, manager_->GetActiveIMEState()->GetActiveInputMethods()->size());
EXPECT_EQ(1, observer.input_method_changed_count_);
- EXPECT_EQ(1, observer.input_method_menu_item_changed_count_);
+ // Menu change is triggered only if current input method was actually changed.
+ EXPECT_EQ(0, observer.input_method_menu_item_changed_count_);
manager_->GetActiveIMEState()->ChangeInputMethod(
ImeIdFromEngineId("xkb:us:dvorak:eng"), false /* show_message */);
EXPECT_FALSE(observer.last_show_message_);
EXPECT_EQ(2, observer.input_method_changed_count_);
- EXPECT_EQ(2, observer.input_method_menu_item_changed_count_);
+ EXPECT_EQ(1, observer.input_method_menu_item_changed_count_);
manager_->GetActiveIMEState()->ChangeInputMethod(
ImeIdFromEngineId("xkb:us:dvorak:eng"), false /* show_message */);
EXPECT_FALSE(observer.last_show_message_);
@@ -383,7 +386,7 @@
// If the same input method ID is passed, PropertyChanged() is not
// notified.
- EXPECT_EQ(2, observer.input_method_menu_item_changed_count_);
+ EXPECT_EQ(1, observer.input_method_menu_item_changed_count_);
manager_->RemoveObserver(&observer);
menu_manager_->RemoveObserver(&observer);
@@ -514,8 +517,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableTwoLayouts) {
// For http://crbug.com/19655#c11 - (8), step 6.
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
@@ -542,8 +545,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableThreeLayouts) {
// For http://crbug.com/19655#c11 - (9).
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us::eng"));
@@ -575,8 +578,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme) {
// For http://crbug.com/19655#c11 - (10).
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
@@ -604,8 +607,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableLayoutAndIme2) {
// For http://crbug.com/19655#c11 - (11).
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
@@ -628,8 +631,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableImes) {
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId(kExt2Engine1Id));
@@ -644,8 +647,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableUnknownIds) {
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back("xkb:tl::tlh"); // Klingon, which is not supported.
@@ -662,8 +665,8 @@
TEST_F(InputMethodManagerImplTest, TestEnableLayoutsThenLock) {
// For http://crbug.com/19655#c11 - (14).
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us::eng"));
@@ -712,8 +715,8 @@
TEST_F(InputMethodManagerImplTest, SwitchInputMethodTest) {
// For http://crbug.com/19655#c11 - (15).
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
@@ -764,8 +767,10 @@
}
TEST_F(InputMethodManagerImplTest, TestXkbSetting) {
+ EXPECT_EQ(0, keyboard_->set_current_keyboard_layout_by_name_count_);
// For http://crbug.com/19655#c11 - (8), step 7-11.
InitComponentExtension();
+ EXPECT_EQ(1, keyboard_->set_current_keyboard_layout_by_name_count_);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
@@ -774,26 +779,26 @@
ids.push_back(ImeIdFromEngineId(kNaclMozcUsId));
EXPECT_TRUE(manager_->GetActiveIMEState()->ReplaceEnabledInputMethods(ids));
EXPECT_EQ(4U, manager_->GetActiveIMEState()->GetNumActiveInputMethods());
- EXPECT_EQ(1, keyboard_->set_current_keyboard_layout_by_name_count_);
+ EXPECT_EQ(2, keyboard_->set_current_keyboard_layout_by_name_count_);
// See input_methods.txt for an expected XKB layout name.
EXPECT_EQ("us(dvorak)", keyboard_->last_layout_);
manager_->GetActiveIMEState()->SwitchToNextInputMethod();
- EXPECT_EQ(2, keyboard_->set_current_keyboard_layout_by_name_count_);
+ EXPECT_EQ(3, keyboard_->set_current_keyboard_layout_by_name_count_);
EXPECT_EQ("us(colemak)", keyboard_->last_layout_);
manager_->GetActiveIMEState()->SwitchToNextInputMethod();
- EXPECT_EQ(3, keyboard_->set_current_keyboard_layout_by_name_count_);
+ EXPECT_EQ(4, keyboard_->set_current_keyboard_layout_by_name_count_);
EXPECT_EQ("jp", keyboard_->last_layout_);
manager_->GetActiveIMEState()->SwitchToNextInputMethod();
- EXPECT_EQ(4, keyboard_->set_current_keyboard_layout_by_name_count_);
+ EXPECT_EQ(5, keyboard_->set_current_keyboard_layout_by_name_count_);
EXPECT_EQ("us", keyboard_->last_layout_);
manager_->GetActiveIMEState()->SwitchToNextInputMethod();
- EXPECT_EQ(5, keyboard_->set_current_keyboard_layout_by_name_count_);
+ EXPECT_EQ(6, keyboard_->set_current_keyboard_layout_by_name_count_);
EXPECT_EQ("us(dvorak)", keyboard_->last_layout_);
// Disable Dvorak.
ids.erase(ids.begin());
EXPECT_TRUE(manager_->GetActiveIMEState()->ReplaceEnabledInputMethods(ids));
EXPECT_EQ(3U, manager_->GetActiveIMEState()->GetNumActiveInputMethods());
- EXPECT_EQ(6, keyboard_->set_current_keyboard_layout_by_name_count_);
+ EXPECT_EQ(7, keyboard_->set_current_keyboard_layout_by_name_count_);
EXPECT_EQ("us(colemak)", keyboard_->last_layout_);
}
@@ -880,8 +885,8 @@
TEST_F(InputMethodManagerImplTest, TestNextInputMethod) {
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
std::vector<std::string> keyboard_layouts;
keyboard_layouts.push_back(ImeIdFromEngineId("xkb:us::eng"));
// For http://crbug.com/19655#c11 - (1)
@@ -921,8 +926,8 @@
TEST_F(InputMethodManagerImplTest, TestPreviousInputMethod) {
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
keydown_accelerator.set_type(ui::ET_KEY_PRESSED);
@@ -998,8 +1003,8 @@
TEST_F(InputMethodManagerImplTest,
TestSwitchToPreviousInputMethodForOneActiveInputMethod) {
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
ui::Accelerator keydown_accelerator(ui::VKEY_SPACE, ui::EF_CONTROL_DOWN);
keydown_accelerator.set_type(ui::ET_KEY_PRESSED);
@@ -1024,8 +1029,8 @@
TEST_F(InputMethodManagerImplTest, TestSwitchInputMethodWithUsLayouts) {
std::string expect_id = ImeIdFromEngineId("xkb:us::eng");
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
std::vector<std::string> keyboard_layouts;
keyboard_layouts.push_back(ImeIdFromEngineId("xkb:us::eng"));
manager_->GetActiveIMEState()->EnableLoginLayouts("en-US", keyboard_layouts);
@@ -1169,8 +1174,8 @@
TEST_F(InputMethodManagerImplTest, TestAddRemoveExtensionInputMethods) {
TestObserver observer;
- manager_->AddObserver(&observer);
InitComponentExtension();
+ manager_->AddObserver(&observer);
manager_->SetUISessionState(InputMethodManager::STATE_BROWSER_SCREEN);
std::vector<std::string> ids;
ids.push_back(ImeIdFromEngineId("xkb:us:dvorak:eng"));
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
index 113d372..853456b 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc
@@ -18,6 +18,20 @@
namespace chromeos {
+namespace {
+
+NetworkPortalDetector::CaptivePortalStatus GetCaptivePortalStatus() {
+ const NetworkState* default_network =
+ NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
+ return default_network
+ ? NetworkPortalDetector::Get()
+ ->GetCaptivePortalState(default_network->guid())
+ .status
+ : NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN;
+}
+
+} // namespace
+
// static
AutoEnrollmentCheckScreen* AutoEnrollmentCheckScreen::Get(
ScreenManager* manager) {
@@ -33,7 +47,8 @@
captive_portal_status_(
NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN),
auto_enrollment_state_(policy::AUTO_ENROLLMENT_STATE_IDLE),
- histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")) {
+ histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")),
+ weak_ptr_factory_(this) {
if (actor_)
actor_->SetDelegate(this);
}
@@ -44,55 +59,60 @@
actor_->SetDelegate(NULL);
}
-void AutoEnrollmentCheckScreen::Start() {
- if (!IsStartNeeded())
- return;
-
- // Make sure the auto-enrollment client is running.
- auto_enrollment_controller_->Start();
-
- auto_enrollment_progress_subscription_ =
- auto_enrollment_controller_->RegisterProgressCallback(
- base::Bind(
- &AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed,
- base::Unretained(this)));
- auto_enrollment_state_ = auto_enrollment_controller_->state();
-
- // NB: AddAndFireObserver below call back into OnPortalDetectionCompleted.
- // This guarantees that the UI gets synced to current state.
- NetworkPortalDetector* portal_detector = NetworkPortalDetector::Get();
- portal_detector->StartDetectionIfIdle();
- portal_detector->AddAndFireObserver(this);
-}
-
void AutoEnrollmentCheckScreen::ClearState() {
- auto_enrollment_state_ = policy::AUTO_ENROLLMENT_STATE_IDLE;
-}
+ auto_enrollment_progress_subscription_.reset();
+ NetworkPortalDetector::Get()->RemoveObserver(this);
-bool AutoEnrollmentCheckScreen::IsStartNeeded() {
- // Check that forced reenrollment is wanted and if the check is needed or we
- // already know the outcome.
- if (AutoEnrollmentController::GetMode() !=
- AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT ||
- auto_enrollment_state_ ==
- policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT ||
- auto_enrollment_state_ == policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT) {
- SignalCompletion();
- return false;
- }
- return true;
+ auto_enrollment_state_ = policy::AUTO_ENROLLMENT_STATE_IDLE;
+ captive_portal_status_ =
+ NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN;
}
void AutoEnrollmentCheckScreen::PrepareToShow() {
}
void AutoEnrollmentCheckScreen::Show() {
- if (IsStartNeeded()) {
- Start();
- if (actor_)
- actor_->Show();
- histogram_helper_->OnScreenShow();
+ // If the decision got made already, don't show the screen at all.
+ if (AutoEnrollmentController::GetMode() !=
+ AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT ||
+ IsCompleted()) {
+ SignalCompletion();
+ return;
}
+
+ // Start from a clean slate.
+ ClearState();
+
+ // Bring up the screen. It's important to do this before updating the UI,
+ // because the latter may switch to the error screen, which needs to stay on
+ // top.
+ actor_->Show();
+ histogram_helper_->OnScreenShow();
+
+ // Set up state change observers.
+ auto_enrollment_progress_subscription_ =
+ auto_enrollment_controller_->RegisterProgressCallback(
+ base::Bind(
+ &AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed,
+ base::Unretained(this)));
+ NetworkPortalDetector* portal_detector = NetworkPortalDetector::Get();
+ portal_detector->AddObserver(this);
+
+ // Perform an initial UI update.
+ NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status =
+ GetCaptivePortalStatus();
+ policy::AutoEnrollmentState new_auto_enrollment_state =
+ auto_enrollment_controller_->state();
+
+ if (!UpdateCaptivePortalStatus(new_captive_portal_status))
+ UpdateAutoEnrollmentState(new_auto_enrollment_state);
+
+ captive_portal_status_ = new_captive_portal_status;
+ auto_enrollment_state_ = new_auto_enrollment_state;
+
+ // Make sure gears are in motion in the background.
+ auto_enrollment_controller_->Start();
+ portal_detector->StartDetectionIfIdle();
}
void AutoEnrollmentCheckScreen::Hide() {
@@ -102,11 +122,6 @@
return WizardController::kAutoEnrollmentCheckScreenName;
}
-void AutoEnrollmentCheckScreen::OnExit() {
- get_base_screen_delegate()->OnExit(
- BaseScreenDelegate::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED);
-}
-
void AutoEnrollmentCheckScreen::OnActorDestroyed(
AutoEnrollmentCheckScreenActor* actor) {
if (actor_ == actor)
@@ -115,19 +130,27 @@
void AutoEnrollmentCheckScreen::OnPortalDetectionCompleted(
const NetworkState* /* network */,
- const NetworkPortalDetector::CaptivePortalState& state) {
- UpdateState(state.status, auto_enrollment_state_);
+ const NetworkPortalDetector::CaptivePortalState& /* state */) {
+ UpdateState();
}
void AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed(
policy::AutoEnrollmentState state) {
- UpdateState(captive_portal_status_, state);
+ if (IsCompleted()) {
+ SignalCompletion();
+ return;
+ }
+
+ UpdateState();
}
-void AutoEnrollmentCheckScreen::UpdateState(
- NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status,
- policy::AutoEnrollmentState new_auto_enrollment_state) {
- // Configure the error screen to show the approriate error message.
+void AutoEnrollmentCheckScreen::UpdateState() {
+ NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status =
+ GetCaptivePortalStatus();
+ policy::AutoEnrollmentState new_auto_enrollment_state =
+ auto_enrollment_controller_->state();
+
+ // Configure the error screen to show the appropriate error message.
if (!UpdateCaptivePortalStatus(new_captive_portal_status))
UpdateAutoEnrollmentState(new_auto_enrollment_state);
@@ -146,23 +169,6 @@
captive_portal_status_ = new_captive_portal_status;
auto_enrollment_state_ = new_auto_enrollment_state;
- // Check whether a decision got made.
- switch (new_auto_enrollment_state) {
- case policy::AUTO_ENROLLMENT_STATE_IDLE:
- NOTREACHED();
- // fall through.
- case policy::AUTO_ENROLLMENT_STATE_PENDING:
- case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
- break;
- case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
- // Server errors don't block OOBE.
- case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
- case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
- // Decision made, ready to proceed.
- SignalCompletion();
- return;
- }
-
// Retry if applicable. This is last so eventual callbacks find consistent
// state.
if (retry)
@@ -234,8 +240,35 @@
void AutoEnrollmentCheckScreen::SignalCompletion() {
NetworkPortalDetector::Get()->RemoveObserver(this);
auto_enrollment_progress_subscription_.reset();
+
+ // Calling Finish() can cause |this| destruction, so let other methods finish
+ // their work before.
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(&AutoEnrollmentCheckScreen::CallOnExit,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AutoEnrollmentCheckScreen::CallOnExit() {
get_base_screen_delegate()->OnExit(
BaseScreenDelegate::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED);
}
+bool AutoEnrollmentCheckScreen::IsCompleted() const {
+ switch (auto_enrollment_controller_->state()) {
+ case policy::AUTO_ENROLLMENT_STATE_IDLE:
+ case policy::AUTO_ENROLLMENT_STATE_PENDING:
+ case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
+ return false;
+ case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
+ // Server errors don't block OOBE.
+ case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
+ case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
+ // Decision made, ready to proceed.
+ return true;
+ }
+ NOTREACHED();
+ return false;
+}
+
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h
index 0eda0a3..eb38b97 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h"
#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.h"
#include "chrome/browser/chromeos/login/screens/error_screen.h"
@@ -35,10 +36,6 @@
static AutoEnrollmentCheckScreen* Get(ScreenManager* manager);
- // Hands over OOBE control to this AutoEnrollmentCheckStep. It'll return the
- // flow back to the caller via the |base_screen_delegate_|'s OnExit function.
- void Start();
-
// Clears the cached state causing the forced enrollment check to be retried.
void ClearState();
@@ -54,7 +51,6 @@
virtual std::string GetName() const override;
// AutoEnrollmentCheckScreenActor::Delegate implementation:
- virtual void OnExit() override;
virtual void OnActorDestroyed(AutoEnrollmentCheckScreenActor* actor) override;
// NetworkPortalDetector::Observer implementation:
@@ -67,9 +63,7 @@
void OnAutoEnrollmentCheckProgressed(policy::AutoEnrollmentState state);
// Handles a state update, updating the UI and saving the state.
- void UpdateState(
- NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status,
- policy::AutoEnrollmentState new_auto_enrollment_state);
+ void UpdateState();
// Configures the UI to reflect |new_captive_portal_status|. Returns true if
// and only if a UI change has been made.
@@ -84,13 +78,16 @@
// Configures the error screen.
void ShowErrorScreen(ErrorScreen::ErrorState error_state);
- // Signals completion. No further code should run after a call to this
- // function as the owner might destroy |this| in response.
+ // Asynchronously signals completion. The owner might destroy |this| in
+ // response, so no code should be run after the completion of a message loop
+ // task, in which this function was called.
void SignalCompletion();
- // Checks if the enrollment status check is needed. It can be disabled either
- // by command line flags, build configuration or might have finished already.
- bool IsStartNeeded();
+ // Terminates the screen.
+ void CallOnExit();
+
+ // Returns whether enrollment check was completed and decision was made.
+ bool IsCompleted() const;
AutoEnrollmentCheckScreenActor* actor_;
AutoEnrollmentController* auto_enrollment_controller_;
@@ -103,6 +100,8 @@
scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_;
+ base::WeakPtrFactory<AutoEnrollmentCheckScreen> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(AutoEnrollmentCheckScreen);
};
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h
index 22fe3ea..1079ad3 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h
@@ -16,9 +16,6 @@
public:
virtual ~Delegate() {}
- // Called when screen is exited.
- virtual void OnExit() = 0;
-
// This method is called, when actor is being destroyed. Note, if Delegate
// is destroyed earlier then it has to call SetDelegate(NULL).
virtual void OnActorDestroyed(AutoEnrollmentCheckScreenActor* actor) = 0;
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
index 88ca35e..4da8c97 100644
--- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
+++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -150,6 +150,8 @@
void AutoEnrollmentController::Retry() {
if (client_)
client_->Retry();
+ else
+ Start();
}
scoped_ptr<AutoEnrollmentController::ProgressCallbackList::Subscription>
diff --git a/chrome/browser/chromeos/login/oobe_browsertest.cc b/chrome/browser/chromeos/login/oobe_browsertest.cc
index c9ae41c..51a33ec 100644
--- a/chrome/browser/chromeos/login/oobe_browsertest.cc
+++ b/chrome/browser/chromeos/login/oobe_browsertest.cc
@@ -8,16 +8,12 @@
#include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
#include "chrome/browser/chromeos/login/ui/webui_login_display.h"
-#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
-#include "chrome/browser/defaults.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/chromeos_switches.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/common/renderer_preferences.h"
#include "content/public/test/test_utils.h"
#include "google_apis/gaia/fake_gaia.h"
#include "google_apis/gaia/gaia_switches.h"
@@ -125,30 +121,4 @@
OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_ENROLLMENT).Wait();
}
-IN_PROC_BROWSER_TEST_F(OobeTest, LinkDisambiguationDefaultRespected) {
- chromeos::LoginDisplayHostImpl* display_host =
- static_cast<chromeos::LoginDisplayHostImpl*>(
- chromeos::LoginDisplayHostImpl::default_host());
- ASSERT_TRUE(display_host);
- chromeos::WebUILoginView* login_view = display_host->GetWebUILoginView();
- ASSERT_TRUE(login_view);
- content::WebContents* web_contents = login_view->GetWebContents();
- ASSERT_TRUE(web_contents);
- content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
- ASSERT_TRUE(prefs);
- // Per crbug/431163 the WiFi selection dropdown doesn't support the link
- // disambiguation popup for gesture events, and this feature is disabled
- // within ChromeOS. Ensure that the web preferences reflect the default.
- if (browser_defaults::kShowLinkDisambiguationPopup) {
- EXPECT_EQ(
- content::TapMultipleTargetsStrategy::
- TAP_MULTIPLE_TARGETS_STRATEGY_POPUP,
- prefs->tap_multiple_targets_strategy);
- } else {
- EXPECT_EQ(
- content::TapMultipleTargetsStrategy::TAP_MULTIPLE_TARGETS_STRATEGY_NONE,
- prefs->tap_multiple_targets_strategy);
- }
-}
-
} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
index 25f9f44..d1a10c3 100644
--- a/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/wizard_controller_browsertest.cc
@@ -216,6 +216,14 @@
MOCK_METHOD0(Show, void());
MOCK_METHOD0(Hide, void());
+ void RealShow() {
+ T::Show();
+ }
+
+ void RealHide() {
+ T::Hide();
+ }
+
private:
scoped_ptr<H> actor_;
};
@@ -786,12 +794,9 @@
EXPECT_CALL(*mock_auto_enrollment_check_screen_, Show()).Times(1);
OnExit(BaseScreenDelegate::UPDATE_INSTALLED);
- AutoEnrollmentCheckScreen* screen =
- AutoEnrollmentCheckScreen::Get(WizardController::default_controller());
- EXPECT_EQ(screen,
- WizardController::default_controller()->current_screen());
+ CheckCurrentScreen(WizardController::kAutoEnrollmentCheckScreenName);
EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
- screen->Start();
+ mock_auto_enrollment_check_screen_->RealShow();
// Wait for auto-enrollment controller to encounter the connection error.
WaitForAutoEnrollmentState(policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
@@ -848,11 +853,8 @@
EXPECT_CALL(*mock_auto_enrollment_check_screen_, Show()).Times(1);
OnExit(BaseScreenDelegate::UPDATE_INSTALLED);
- AutoEnrollmentCheckScreen* screen =
- AutoEnrollmentCheckScreen::Get(WizardController::default_controller());
- EXPECT_EQ(screen,
- WizardController::default_controller()->current_screen());
- screen->Start();
+ CheckCurrentScreen(WizardController::kAutoEnrollmentCheckScreenName);
+ mock_auto_enrollment_check_screen_->RealShow();
EXPECT_EQ(policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT,
LoginDisplayHostImpl::default_host()
->GetAutoEnrollmentController()
@@ -880,12 +882,9 @@
EXPECT_CALL(*mock_auto_enrollment_check_screen_, Show()).Times(1);
OnExit(BaseScreenDelegate::UPDATE_INSTALLED);
- AutoEnrollmentCheckScreen* screen =
- AutoEnrollmentCheckScreen::Get(WizardController::default_controller());
- EXPECT_EQ(screen,
- WizardController::default_controller()->current_screen());
+ CheckCurrentScreen(WizardController::kAutoEnrollmentCheckScreenName);
EXPECT_CALL(*mock_auto_enrollment_check_screen_, Hide()).Times(1);
- screen->Start();
+ mock_auto_enrollment_check_screen_->RealShow();
// Wait for auto-enrollment controller to encounter the connection error.
WaitForAutoEnrollmentState(policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR);
diff --git a/chrome/browser/chromeos/net/client_cert_filter_chromeos.cc b/chrome/browser/chromeos/net/client_cert_filter_chromeos.cc
index 1ff3a78..6f735b8 100644
--- a/chrome/browser/chromeos/net/client_cert_filter_chromeos.cc
+++ b/chrome/browser/chromeos/net/client_cert_filter_chromeos.cc
@@ -26,7 +26,6 @@
DCHECK(!init_called_);
init_called_ = true;
- init_callback_ = callback;
if (use_system_slot_) {
system_slot_ = crypto::GetSystemNSSKeySlot(
base::Bind(&ClientCertFilterChromeOS::GotSystemSlot,
@@ -38,7 +37,11 @@
weak_ptr_factory_.GetWeakPtr())).Pass();
// Do not call back if we initialized synchronously.
- return InitIfSlotsAvailable();
+ if (InitIfSlotsAvailable())
+ return true;
+
+ init_callback_ = callback;
+ return false;
}
bool ClientCertFilterChromeOS::IsCertAllowed(
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
index c3d2d6f..4f0903e 100644
--- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -176,6 +176,9 @@
const char kGoodExtensionCRXPath[] = "extensions/good.crx";
const char kGoodExtensionVersion[] = "1.0";
const char kPackagedAppCRXPath[] = "extensions/platform_apps/app_window_2.crx";
+const char kShowManagedStorageID[] = "ongnjlefhnoajpbodoldndkbkdgfomlp";
+const char kShowManagedStorageCRXPath[] = "extensions/show_managed_storage.crx";
+const char kShowManagedStorageVersion[] = "1.0";
const char kExternalData[] = "External data";
const char kExternalDataURL[] = "http://localhost/external_data";
@@ -382,6 +385,12 @@
return user_manager::UserManager::Get()->IsSessionStarted();
}
+void PolicyChangedCallback(const base::Closure& callback,
+ const base::Value* old_value,
+ const base::Value* new_value) {
+ callback.Run();
+}
+
} // namespace
class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest,
@@ -1941,6 +1950,104 @@
.id());
}
+IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyForExtensions) {
+ // Set up a test update server for the Show Managed Storage app.
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ TestingUpdateManifestProvider testing_update_manifest_provider(
+ kRelativeUpdateURL);
+ testing_update_manifest_provider.AddUpdate(
+ kShowManagedStorageID,
+ kShowManagedStorageVersion,
+ embedded_test_server()->GetURL(std::string("/") +
+ kShowManagedStorageCRXPath));
+ embedded_test_server()->RegisterRequestHandler(
+ base::Bind(&TestingUpdateManifestProvider::HandleRequest,
+ base::Unretained(&testing_update_manifest_provider)));
+
+ // Force-install the Show Managed Storage app. This app can be installed in
+ // public sessions because it's whitelisted for testing purposes.
+ em::StringList* forcelist = device_local_account_policy_.payload()
+ .mutable_extensioninstallforcelist()->mutable_value();
+ forcelist->add_entries(base::StringPrintf(
+ "%s;%s",
+ kShowManagedStorageID,
+ embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
+
+ // Set a policy for the app at the policy testserver.
+ test_server_.UpdatePolicyData(dm_protocol::kChromeExtensionPolicyType,
+ kShowManagedStorageID,
+ "{"
+ " \"string\": {"
+ " \"Value\": \"policy test value one\""
+ " }"
+ "}");
+
+ UploadAndInstallDeviceLocalAccountPolicy();
+ AddPublicSessionToDevicePolicy(kAccountId1);
+ WaitForPolicy();
+
+ // Observe the app installation after login.
+ content::WindowedNotificationObserver extension_observer(
+ extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
+ base::Bind(DoesInstallSuccessReferToId, kShowManagedStorageID));
+ ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
+ WaitForSessionStart();
+ extension_observer.Wait();
+
+ // Verify that the app was installed.
+ Profile* profile = GetProfileForTest();
+ ASSERT_TRUE(profile);
+ ExtensionService* extension_service =
+ extensions::ExtensionSystem::Get(profile)->extension_service();
+ EXPECT_TRUE(extension_service->GetExtensionById(kShowManagedStorageID, true));
+
+ // Wait for the app policy if it hasn't been fetched yet.
+ ProfilePolicyConnector* connector =
+ ProfilePolicyConnectorFactory::GetForProfile(profile);
+ ASSERT_TRUE(connector);
+ PolicyService* policy_service = connector->policy_service();
+ ASSERT_TRUE(policy_service);
+ const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kShowManagedStorageID);
+ if (policy_service->GetPolicies(ns).empty()) {
+ PolicyChangeRegistrar policy_registrar(policy_service, ns);
+ base::RunLoop run_loop;
+ policy_registrar.Observe(
+ "string", base::Bind(&PolicyChangedCallback, run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+
+ // Verify that the app policy was set.
+ base::StringValue expected_value("policy test value one");
+ EXPECT_TRUE(base::Value::Equals(
+ &expected_value,
+ policy_service->GetPolicies(ns).GetValue("string")));
+
+ // Now update the policy at the server.
+ test_server_.UpdatePolicyData(dm_protocol::kChromeExtensionPolicyType,
+ kShowManagedStorageID,
+ "{"
+ " \"string\": {"
+ " \"Value\": \"policy test value two\""
+ " }"
+ "}");
+
+ // And issue a policy refresh.
+ {
+ PolicyChangeRegistrar policy_registrar(policy_service, ns);
+ base::RunLoop run_loop;
+ policy_registrar.Observe(
+ "string", base::Bind(&PolicyChangedCallback, run_loop.QuitClosure()));
+ policy_service->RefreshPolicies(base::Closure());
+ run_loop.Run();
+ }
+
+ // Verify that the app policy was updated.
+ base::StringValue expected_new_value("policy test value two");
+ EXPECT_TRUE(base::Value::Equals(
+ &expected_new_value,
+ policy_service->GetPolicies(ns).GetValue("string")));
+}
+
class TermsOfServiceDownloadTest : public DeviceLocalAccountTest,
public testing::WithParamInterface<bool> {
};
diff --git a/chrome/browser/chromeos/policy/device_local_account_extension_tracker.cc b/chrome/browser/chromeos/policy/device_local_account_extension_tracker.cc
index 9b86e9b..546c5bd 100644
--- a/chrome/browser/chromeos/policy/device_local_account_extension_tracker.cc
+++ b/chrome/browser/chromeos/policy/device_local_account_extension_tracker.cc
@@ -12,6 +12,7 @@
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/core/common/schema.h"
+#include "components/policy/core/common/schema_map.h"
#include "components/policy/core/common/schema_registry.h"
#include "extensions/browser/pref_names.h"
@@ -74,6 +75,17 @@
for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, it.key());
+ if (schema_registry_->schema_map()->GetSchema(ns)) {
+ // Important detail: Don't register the component again if it already
+ // has a schema! If the session already started for this public session
+ // then the real Schema for the extension has already been set by the
+ // ManagedValueStoreCache::ExtensionTracker. Do not override that schema
+ // with an invalid one now, or the policy for the extension will be
+ // dropped.
+ // However, if the forcelist is updated then we need to register the new
+ // component ID so that its remote policy data can be fetched.
+ continue;
+ }
schema_registry_->RegisterComponent(ns, Schema());
}
diff --git a/chrome/browser/chromeos/policy/device_local_account_extension_tracker.h b/chrome/browser/chromeos/policy/device_local_account_extension_tracker.h
index a357986..2b24d0a 100644
--- a/chrome/browser/chromeos/policy/device_local_account_extension_tracker.h
+++ b/chrome/browser/chromeos/policy/device_local_account_extension_tracker.h
@@ -16,6 +16,11 @@
// Helper class that keeps all the extensions that a device-local account uses
// registered in a SchemaRegistry.
+// This makes it possible to precache the policy for extensions for public
+// sessions before the session is started (e.g. during enrollment).
+// Otherwise, the ComponentCloudPolicyService would ignore the
+// PolicyFetchResponses from the DMServer because the SchemaRegistry for this
+// account doesn't have this extension "installed".
class DeviceLocalAccountExtensionTracker : public CloudPolicyStore::Observer {
public:
DeviceLocalAccountExtensionTracker(
diff --git a/chrome/browser/defaults.cc b/chrome/browser/defaults.cc
index ff39b1d..6d6b6b6 100644
--- a/chrome/browser/defaults.cc
+++ b/chrome/browser/defaults.cc
@@ -16,14 +16,6 @@
const int kOmniboxFontPixelSize = 16;
-#if defined(TOOLKIT_VIEWS)
-#if defined(OS_WIN)
-const bool kShowLinkDisambiguationPopup = true;
-#else
-const bool kShowLinkDisambiguationPopup = false;
-#endif
-#endif
-
#if defined(OS_CHROMEOS) || defined(OS_MACOSX)
const bool kBrowserAliveWithNoWindows = true;
const bool kShowExitMenuItem = false;
diff --git a/chrome/browser/defaults.h b/chrome/browser/defaults.h
index 157d561..41b16d6 100644
--- a/chrome/browser/defaults.h
+++ b/chrome/browser/defaults.h
@@ -33,12 +33,6 @@
const int kMiniTabWidth = 56;
#endif
-#if defined(TOOLKIT_VIEWS)
-// Whether to show a Link Disambiguation Popup Bubble if the browser detects an
-// ambiguous touch event.
-extern const bool kShowLinkDisambiguationPopup;
-#endif
-
// Can the browser be alive without any browser windows?
extern const bool kBrowserAliveWithNoWindows;
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc
index b00c414..c513036 100644
--- a/chrome/browser/extensions/api/identity/identity_api.cc
+++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -11,7 +11,6 @@
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
-#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
@@ -20,13 +19,14 @@
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/common/extensions/api/identity.h"
-#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/common/profile_management_switches.h"
@@ -845,14 +845,15 @@
return RespondNow(Error(identity_constants::kOffTheRecord));
}
+ AccountTrackerService::AccountInfo account =
+ AccountTrackerServiceFactory::GetForProfile(GetProfile())
+ ->GetAccountInfo(GetPrimaryAccountId(GetProfile()));
api::identity::ProfileUserInfo profile_user_info;
if (extension()->permissions_data()->HasAPIPermission(
APIPermission::kIdentityEmail)) {
- profile_user_info.email =
- GetProfile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername);
+ profile_user_info.email = account.email;
}
- profile_user_info.id =
- GetProfile()->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId);
+ profile_user_info.id = account.gaia;
return RespondNow(OneArgument(profile_user_info.ToValue().release()));
}
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc
index 6d18d6b..a2881ef 100644
--- a/chrome/browser/extensions/api/identity/identity_apitest.cc
+++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
+#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/fake_account_reconcilor.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
@@ -33,6 +34,7 @@
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/test_switches.h"
#include "components/crx_file/id_util.h"
+#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "components/signin/core/common/signin_pref_names.h"
@@ -530,7 +532,70 @@
EXPECT_TRUE(ExpectGetAccounts(only_primary));
}
-class IdentityGetProfileUserInfoFunctionTest : public ExtensionBrowserTest {
+class IdentityTestWithSignin : public AsyncExtensionBrowserTest {
+ public:
+ void SetUpInProcessBrowserTestFixture() override {
+ AsyncExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
+
+ will_create_browser_context_services_subscription_ =
+ BrowserContextDependencyManager::GetInstance()
+ ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
+ base::Bind(&IdentityTestWithSignin::
+ OnWillCreateBrowserContextServices,
+ base::Unretained(this)))
+ .Pass();
+ }
+
+ void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
+ // Replace the signin manager and token service with fakes. Do this ahead of
+ // creating the browser so that a bunch of classes don't register as
+ // observers and end up needing to unregister when the fake is substituted.
+ SigninManagerFactory::GetInstance()->SetTestingFactory(
+ context, &FakeSigninManagerBase::Build);
+ ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
+ context, &BuildFakeProfileOAuth2TokenService);
+ AccountReconcilorFactory::GetInstance()->SetTestingFactory(
+ context, &FakeAccountReconcilor::Build);
+ }
+
+ void SetUpOnMainThread() override {
+ AsyncExtensionBrowserTest::SetUpOnMainThread();
+
+ // Grab references to the fake signin manager and token service.
+ signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
+ SigninManagerFactory::GetInstance()->GetForProfile(profile()));
+ ASSERT_TRUE(signin_manager_);
+ token_service_ = static_cast<FakeProfileOAuth2TokenService*>(
+ ProfileOAuth2TokenServiceFactory::GetInstance()->GetForProfile(
+ profile()));
+ ASSERT_TRUE(token_service_);
+ }
+
+ protected:
+ void SignIn(const std::string account_key) {
+#if defined(OS_CHROMEOS)
+ signin_manager_->SetAuthenticatedUsername(account_key);
+#else
+ signin_manager_->SignIn(account_key, "password");
+#endif
+ token_service_->IssueRefreshTokenForUser(account_key, "refresh_token");
+ }
+
+ void SignIn(const std::string& account_key, const std::string& gaia) {
+ AccountTrackerService* account_tracker =
+ AccountTrackerServiceFactory::GetForProfile(profile());
+ account_tracker->SeedAccountInfo(gaia, account_key);
+ SignIn(account_key);
+ }
+
+ FakeSigninManagerForTesting* signin_manager_;
+ FakeProfileOAuth2TokenService* token_service_;
+
+ scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
+ will_create_browser_context_services_subscription_;
+};
+
+class IdentityGetProfileUserInfoFunctionTest : public IdentityTestWithSignin {
protected:
scoped_ptr<api::identity::ProfileUserInfo> RunGetProfileUserInfo() {
scoped_refptr<IdentityGetProfileUserInfoFunction> func(
@@ -568,11 +633,7 @@
}
IN_PROC_BROWSER_TEST_F(IdentityGetProfileUserInfoFunctionTest, SignedIn) {
- profile()->GetPrefs()
- ->SetString(prefs::kGoogleServicesUsername, "president@example.com");
- profile()->GetPrefs()
- ->SetString(prefs::kGoogleServicesUserAccountId, "12345");
-
+ SignIn("president@example.com", "12345");
scoped_ptr<api::identity::ProfileUserInfo> info =
RunGetProfileUserInfoWithEmail();
EXPECT_EQ("president@example.com", info->email);
@@ -588,69 +649,19 @@
IN_PROC_BROWSER_TEST_F(IdentityGetProfileUserInfoFunctionTest,
SignedInNoEmail) {
- profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
- "president@example.com");
- profile()->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId,
- "12345");
-
+ SignIn("president@example.com", "12345");
scoped_ptr<api::identity::ProfileUserInfo> info = RunGetProfileUserInfo();
EXPECT_TRUE(info->email.empty());
EXPECT_EQ("12345", info->id);
}
-class GetAuthTokenFunctionTest : public AsyncExtensionBrowserTest {
+class GetAuthTokenFunctionTest : public IdentityTestWithSignin {
public:
void SetUpCommandLine(CommandLine* command_line) override {
- AsyncExtensionBrowserTest::SetUpCommandLine(command_line);
+ IdentityTestWithSignin::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kExtensionsMultiAccount);
}
- void SetUpInProcessBrowserTestFixture() override {
- AsyncExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
-
- will_create_browser_context_services_subscription_ =
- BrowserContextDependencyManager::GetInstance()
- ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
- base::Bind(&GetAuthTokenFunctionTest::
- OnWillCreateBrowserContextServices,
- base::Unretained(this)))
- .Pass();
- }
-
- void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
- // Replace the signin manager and token service with fakes. Do this ahead of
- // creating the browser so that a bunch of classes don't register as
- // observers and end up needing to unregister when the fake is substituted.
- SigninManagerFactory::GetInstance()->SetTestingFactory(
- context, &FakeSigninManagerBase::Build);
- ProfileOAuth2TokenServiceFactory::GetInstance()->SetTestingFactory(
- context, &BuildFakeProfileOAuth2TokenService);
- AccountReconcilorFactory::GetInstance()->SetTestingFactory(
- context, &FakeAccountReconcilor::Build);
- }
-
- void SetUpOnMainThread() override {
- AsyncExtensionBrowserTest::SetUpOnMainThread();
-
- // Grab references to the fake signin manager and token service.
- signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
- SigninManagerFactory::GetInstance()->GetForProfile(profile()));
- ASSERT_TRUE(signin_manager_);
- token_service_ = static_cast<FakeProfileOAuth2TokenService*>(
- ProfileOAuth2TokenServiceFactory::GetInstance()->GetForProfile(
- profile()));
- ASSERT_TRUE(token_service_);
- }
-
- void SignIn(const std::string account_key) {
-#if defined(OS_CHROMEOS)
- signin_manager_->SetAuthenticatedUsername(account_key);
-#else
- signin_manager_->SignIn(account_key, "password");
-#endif
- token_service_->IssueRefreshTokenForUser(account_key, "refresh_token");
- }
-
void IssueLoginRefreshTokenForAccount(const std::string account_key) {
token_service_->IssueRefreshTokenForUser(account_key, "refresh_token");
}
@@ -675,9 +686,6 @@
AS_COMPONENT = 4
};
- FakeSigninManagerForTesting* signin_manager_;
- FakeProfileOAuth2TokenService* token_service_;
-
~GetAuthTokenFunctionTest() override {}
// Helper to create an extension with specific OAuth2Info fields set.
@@ -744,9 +752,6 @@
private:
std::string extension_id_;
std::set<std::string> oauth_scopes_;
-
- scoped_ptr<base::CallbackList<void(content::BrowserContext*)>::Subscription>
- will_create_browser_context_services_subscription_;
};
IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest,
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
index e334630..9e7e94c 100644
--- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
+++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h"
#include "base/json/json_string_value_serializer.h"
+#include "base/prefs/pref_service.h"
#include "base/sys_info.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -13,6 +14,7 @@
#include "chrome/browser/sync/about_sync_util.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/common/chrome_version_info.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/extension.h"
@@ -23,6 +25,7 @@
const char kSyncDataKey[] = "about_sync_data";
const char kExtensionsListKey[] = "extensions";
+const char kDataReductionProxyKey[] = "data_reduction_proxy";
const char kChromeVersionTag[] = "CHROME VERSION";
#if !defined(OS_CHROMEOS)
const char kOsVersionTag[] = "OS VERSION";
@@ -57,6 +60,7 @@
PopulateSyncLogs(&response);
PopulateExtensionInfoLogs(&response);
+ PopulateDataReductionProxyLogs(&response);
callback.Run(&response);
}
@@ -133,4 +137,15 @@
(*response)[kExtensionsListKey] = extensions_list;
}
+void ChromeInternalLogSource::PopulateDataReductionProxyLogs(
+ SystemLogsResponse* response) {
+ PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
+ bool is_data_reduction_proxy_enabled = prefs->HasPrefPath(
+ data_reduction_proxy::prefs::kDataReductionProxyEnabled) &&
+ prefs->GetBoolean(
+ data_reduction_proxy::prefs::kDataReductionProxyEnabled);
+ (*response)[kDataReductionProxyKey] = is_data_reduction_proxy_enabled ?
+ "enabled" : "disabled";
+}
+
} // namespace system_logs
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h
index f533965..a4a7c61 100644
--- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h
+++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h
@@ -21,6 +21,7 @@
private:
void PopulateSyncLogs(SystemLogsResponse* response);
void PopulateExtensionInfoLogs(SystemLogsResponse* response);
+ void PopulateDataReductionProxyLogs(SystemLogsResponse* response);
DISALLOW_COPY_AND_ASSIGN(ChromeInternalLogSource);
};
diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc
index fc0ada5..bf1e2e0 100644
--- a/chrome/browser/renderer_preferences_util.cc
+++ b/chrome/browser/renderer_preferences_util.cc
@@ -22,7 +22,6 @@
#endif
#if defined(TOOLKIT_VIEWS)
-#include "chrome/browser/defaults.h"
#include "ui/views/controls/textfield/textfield.h"
#endif
@@ -70,14 +69,6 @@
#if defined(TOOLKIT_VIEWS)
prefs->caret_blink_interval = views::Textfield::GetCaretBlinkMs() / 1000.0;
- if (browser_defaults::kShowLinkDisambiguationPopup) {
- prefs->tap_multiple_targets_strategy =
- content::TapMultipleTargetsStrategy::
- TAP_MULTIPLE_TARGETS_STRATEGY_POPUP;
- } else {
- prefs->tap_multiple_targets_strategy =
- content::TapMultipleTargetsStrategy::TAP_MULTIPLE_TARGETS_STRATEGY_NONE;
- }
#endif
#if defined(USE_AURA) && defined(OS_LINUX) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/resources/easy_unlock/manifest.json b/chrome/browser/resources/easy_unlock/manifest.json
index 9c56540..b4e6a59 100644
--- a/chrome/browser/resources/easy_unlock/manifest.json
+++ b/chrome/browser/resources/easy_unlock/manifest.json
@@ -1,6 +1,6 @@
{
- "name": "Easy Unlock",
- "description": "This app sets up unlocking the device with a phone.",
+ "name": "Smart Lock",
+ "description": "This app allows you to unlock your device when in proximity to your phone.",
"version": "1.0",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqOUeUl1nC6qTz6WwVUIaAJ4ukXVzgeCAumX4TZlCHFk5DLHImHLDBxakyVGaQFLS9iEQ3tDTsJLIoA+FkbWKNX7bvDW/qM89CeVNZsIZRGw898m8J78N6dJHwP9aZSI8CpoMK2KvjANpuj1tdWs1OM6v65zRUu6y4Mq876dr5AcPiuznGxl8jekagBwGu8jqMySsJxLazj/EfQ3W1E7mpyHd0Z4C1qNwJoFlUQeMjn6gfPZqa06BLU6YznzCUesiyjFK3d1vzbN54ZkVxhcA6ekwLKYLqKykBFLmIQG0gkNNePzcGXju8p34dGJgkcZw0sOXrtNaLSe1su0zfcniIwIDAQAB",
diff --git a/chrome/browser/resources/gaia_auth/main.js b/chrome/browser/resources/gaia_auth/main.js
index 7523ceb..05271fb 100644
--- a/chrome/browser/resources/gaia_auth/main.js
+++ b/chrome/browser/resources/gaia_auth/main.js
@@ -351,9 +351,16 @@
*/
onCompleteLogin_: function(msg) {
if (!msg.email || !msg.gaiaId || !msg.sessionIndex) {
- console.error('Missing fields to complete login.');
- window.parent.postMessage({method: 'missingGaiaInfo'}, this.parentPage_);
- return;
+ // On desktop, if the skipForNow message field is set, send it to handler.
+ // This does not require the email, gaiaid or session to be valid.
+ if (this.desktopMode_ && msg.skipForNow) {
+ this.completeLogin_(msg);
+ } else {
+ console.error('Missing fields to complete login.');
+ window.parent.postMessage({method: 'missingGaiaInfo'},
+ this.parentPage_);
+ return;
+ }
}
// Skip SAML extra steps for desktop flow and non-SAML flow.
diff --git a/chrome/browser/safe_browsing/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection_service.cc
index 30f2523..c8f2e7f 100644
--- a/chrome/browser/safe_browsing/download_protection_service.cc
+++ b/chrome/browser/safe_browsing/download_protection_service.cc
@@ -312,6 +312,7 @@
switch (reason) {
case REASON_EMPTY_URL_CHAIN:
case REASON_INVALID_URL:
+ case REASON_UNSUPPORTED_URL_SCHEME:
PostFinishTask(UNKNOWN, reason);
return;
@@ -462,11 +463,15 @@
return false;
}
const GURL& final_url = item.GetUrlChain().back();
- if (!final_url.is_valid() || final_url.is_empty() ||
- !final_url.IsStandard() || final_url.SchemeIsFile()) {
+ if (!final_url.is_valid() || final_url.is_empty()) {
*reason = REASON_INVALID_URL;
return false;
}
+ if ((!final_url.IsStandard() && !final_url.SchemeIsBlob()) ||
+ final_url.SchemeIsFile()) {
+ *reason = REASON_UNSUPPORTED_URL_SCHEME;
+ return false;
+ }
if (!download_protection_util::IsBinaryFile(target_path)) {
*reason = REASON_NOT_BINARY_FILE;
return false;
diff --git a/chrome/browser/safe_browsing/download_protection_service.h b/chrome/browser/safe_browsing/download_protection_service.h
index a42addd..603ce8d 100644
--- a/chrome/browser/safe_browsing/download_protection_service.h
+++ b/chrome/browser/safe_browsing/download_protection_service.h
@@ -157,6 +157,7 @@
REASON_ARCHIVE_WITHOUT_BINARIES,
REASON_DOWNLOAD_DANGEROUS_HOST,
REASON_DOWNLOAD_POTENTIALLY_UNWANTED,
+ REASON_UNSUPPORTED_URL_SCHEME,
REASON_MAX // Always add new values before this one.
};
@@ -172,6 +173,8 @@
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadHTTPS);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
+ CheckClientDownloadBlob);
+ FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadZip);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadFetchFailed);
diff --git a/chrome/browser/safe_browsing/download_protection_service_unittest.cc b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
index 84fd01d..fca1671 100644
--- a/chrome/browser/safe_browsing/download_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection_service_unittest.cc
@@ -872,6 +872,62 @@
#endif
}
+TEST_F(DownloadProtectionServiceTest, CheckClientDownloadBlob) {
+ ClientDownloadResponse response;
+ response.set_verdict(ClientDownloadResponse::DANGEROUS);
+ net::FakeURLFetcherFactory factory(NULL);
+ factory.SetFakeResponse(DownloadProtectionService::GetDownloadRequestUrl(),
+ response.SerializeAsString(), net::HTTP_OK,
+ net::URLRequestStatus::SUCCESS);
+
+ base::FilePath a_tmp(FILE_PATH_LITERAL("a.tmp"));
+ base::FilePath a_exe(FILE_PATH_LITERAL("a.exe"));
+ std::vector<GURL> url_chain;
+ url_chain.push_back(
+ GURL("blob:http://www.evil.com/50b85f60-71e4-11e4-82f8-0800200c9a66"));
+ GURL referrer("http://www.google.com/");
+ std::string hash = "hash";
+
+ content::MockDownloadItem item;
+ EXPECT_CALL(item, GetFullPath()).WillRepeatedly(ReturnRef(a_tmp));
+ EXPECT_CALL(item, GetTargetFilePath()).WillRepeatedly(ReturnRef(a_exe));
+ EXPECT_CALL(item, GetUrlChain()).WillRepeatedly(ReturnRef(url_chain));
+ EXPECT_CALL(item, GetReferrerUrl()).WillRepeatedly(ReturnRef(referrer));
+ EXPECT_CALL(item, GetTabUrl()).WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
+ EXPECT_CALL(item, GetTabReferrerUrl())
+ .WillRepeatedly(ReturnRef(GURL::EmptyGURL()));
+ EXPECT_CALL(item, GetHash()).WillRepeatedly(ReturnRef(hash));
+ EXPECT_CALL(item, GetReceivedBytes()).WillRepeatedly(Return(100));
+ EXPECT_CALL(item, HasUserGesture()).WillRepeatedly(Return(true));
+ EXPECT_CALL(item, GetRemoteAddress()).WillRepeatedly(Return(""));
+
+ EXPECT_CALL(*sb_service_->mock_database_manager(),
+ MatchDownloadWhitelistUrl(_)).WillRepeatedly(Return(false));
+ EXPECT_CALL(*binary_feature_extractor_.get(), CheckSignature(a_tmp, _))
+ .Times(1);
+ EXPECT_CALL(*binary_feature_extractor_.get(), ExtractImageHeaders(a_tmp, _))
+ .Times(1);
+
+ download_service_->CheckClientDownload(
+ &item,
+ base::Bind(&DownloadProtectionServiceTest::CheckDoneCallback,
+ base::Unretained(this)));
+ MessageLoop::current()->Run();
+#if defined(OS_WIN)
+ EXPECT_TRUE(IsResult(DownloadProtectionService::DANGEROUS));
+#else
+ EXPECT_TRUE(IsResult(DownloadProtectionService::UNKNOWN));
+#endif
+
+#if defined(OS_WIN) || defined(OS_MACOSX)
+ // OSX sends pings for evaluation purposes.
+ EXPECT_TRUE(HasClientDownloadRequest());
+ ClearClientDownloadRequest();
+#else
+ EXPECT_FALSE(HasClientDownloadRequest());
+#endif
+}
+
TEST_F(DownloadProtectionServiceTest, CheckClientDownloadZip) {
ClientDownloadResponse response;
response.set_verdict(ClientDownloadResponse::SAFE);
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
index 6a6acd0..d8bbb5d 100644
--- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager.cc
@@ -587,17 +587,19 @@
if (iter != pending_items_.end()) {
const ItemData& item_data = iter->second;
download = item_data.item; // non-null if not destroyed.
- if (item_data.removed)
+ if (item_data.removed) {
RemoveMetadata();
- else if (!item_data.last_opened_time.is_null())
+ download = nullptr;
+ } else if (!item_data.last_opened_time.is_null()) {
UpdateLastOpenedTime(item_data.last_opened_time);
+ }
}
}
// Stop observing all items.
ClearPendingItems();
- // If the download was known, observe it from here on out.
+ // If the download was known and not removed, observe it from here on out.
if (download) {
download->AddObserver(this);
item_ = download;
diff --git a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
index 538a7da..c722923 100644
--- a/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/download_metadata_manager_unittest.cc
@@ -307,6 +307,10 @@
if (details_loaded_)
RunAllTasks();
+ // In http://crbug.com/433928, open after removal during load caused a crash.
+ if (item_action_ == REMOVED)
+ test_item_->NotifyObserversDownloadOpened();
+
MockDownloadDetailsGetter details_getter;
if (metadata_file_present_ && item_action_ != REMOVED) {
// The file is present, so expect that the callback is invoked with the
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index 9281513..93a25a4 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -7,7 +7,6 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
-#include "base/metrics/field_trial.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
@@ -27,6 +26,7 @@
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/proximity_auth/switches.h"
#include "components/user_manager/user.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
@@ -81,19 +81,8 @@
// static
bool EasyUnlockService::IsSignInEnabled() {
-#if defined(OS_CHROMEOS)
- const std::string group_name =
- base::FieldTrialList::FindFullName("EasySignIn");
-
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- chromeos::switches::kDisableEasySignin)) {
- return false;
- }
-
- return group_name == "Enable";
-#else
- return false;
-#endif
+ return !CommandLine::ForCurrentProcess()->HasSwitch(
+ proximity_auth::switches::kDisableEasySignin);
}
class EasyUnlockService::BluetoothDetector
@@ -246,6 +235,11 @@
if (shut_down_)
return false;
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ proximity_auth::switches::kDisableEasyUnlock)) {
+ return false;
+ }
+
if (!IsAllowedInternal())
return false;
diff --git a/chrome/browser/signin/easy_unlock_service_browsertest_chromeos.cc b/chrome/browser/signin/easy_unlock_service_browsertest_chromeos.cc
index 10f5f07..e68a27c 100644
--- a/chrome/browser/signin/easy_unlock_service_browsertest_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_service_browsertest_chromeos.cc
@@ -22,6 +22,7 @@
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/core/common/policy_types.h"
+#include "components/proximity_auth/switches.h"
#include "components/user_manager/user_manager.h"
#include "content/public/common/content_switches.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
@@ -136,11 +137,41 @@
DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceTest);
};
-IN_PROC_BROWSER_TEST_F(EasyUnlockServiceTest, NoFinchNoService) {
+IN_PROC_BROWSER_TEST_F(EasyUnlockServiceTest, DefaultOn) {
+ EXPECT_TRUE(service()->IsAllowed());
+#if defined(GOOGLE_CHROME_BUILD)
+ EXPECT_TRUE(HasEasyUnlockApp());
+#endif
+}
+
+#if defined(GOOGLE_CHROME_BUILD)
+IN_PROC_BROWSER_TEST_F(EasyUnlockServiceTest, UnloadsOnSuspend) {
+ EXPECT_TRUE(HasEasyUnlockApp());
+ power_manager_client()->SendSuspendImminent();
+ EXPECT_FALSE(HasEasyUnlockApp());
+ power_manager_client()->SendSuspendDone();
+ EXPECT_TRUE(HasEasyUnlockApp());
+}
+#endif
+
+IN_PROC_BROWSER_TEST_F(EasyUnlockServiceTest, PolicyOveride) {
+ EXPECT_TRUE(service()->IsAllowed());
+#if defined(GOOGLE_CHROME_BUILD)
+ EXPECT_TRUE(HasEasyUnlockApp());
+#endif
+
+ // Overridden by policy.
+ SetEasyUnlockAllowedPolicy(false);
EXPECT_FALSE(service()->IsAllowed());
#if defined(GOOGLE_CHROME_BUILD)
EXPECT_FALSE(HasEasyUnlockApp());
#endif
+
+ SetEasyUnlockAllowedPolicy(true);
+ EXPECT_TRUE(service()->IsAllowed());
+#if defined(GOOGLE_CHROME_BUILD)
+ EXPECT_TRUE(HasEasyUnlockApp());
+#endif
}
class EasyUnlockServiceNoBluetoothTest : public EasyUnlockServiceTest {
@@ -165,78 +196,29 @@
#endif
}
-class EasyUnlockServiceFinchEnabledTest : public EasyUnlockServiceTest {
+class EasyUnlockServiceDisabledTest : public EasyUnlockServiceTest {
public:
- EasyUnlockServiceFinchEnabledTest() {}
- virtual ~EasyUnlockServiceFinchEnabledTest() {}
+ EasyUnlockServiceDisabledTest() {}
+ virtual ~EasyUnlockServiceDisabledTest() {}
// InProcessBrowserTest:
virtual void SetUpCommandLine(CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kForceFieldTrials,
- "EasyUnlock/Enable/");
+ command_line->AppendSwitch(proximity_auth::switches::kDisableEasyUnlock);
}
private:
- DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceFinchEnabledTest);
+ DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceDisabledTest);
};
-IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchEnabledTest, Enabled) {
- EXPECT_TRUE(service()->IsAllowed());
-#if defined(GOOGLE_CHROME_BUILD)
- EXPECT_TRUE(HasEasyUnlockApp());
-#endif
-}
-
-#if defined(GOOGLE_CHROME_BUILD)
-IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchEnabledTest, UnloadsOnSuspend) {
- EXPECT_TRUE(HasEasyUnlockApp());
- power_manager_client()->SendSuspendImminent();
- EXPECT_FALSE(HasEasyUnlockApp());
- power_manager_client()->SendSuspendDone();
- EXPECT_TRUE(HasEasyUnlockApp());
-}
-#endif
-
-// Tests that policy can override finch to turn easy unlock off.
-IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchEnabledTest, PolicyOveride) {
- EXPECT_TRUE(service()->IsAllowed());
-#if defined(GOOGLE_CHROME_BUILD)
- EXPECT_TRUE(HasEasyUnlockApp());
-#endif
-
- // Overridden by policy.
- SetEasyUnlockAllowedPolicy(false);
+IN_PROC_BROWSER_TEST_F(EasyUnlockServiceDisabledTest, Disabled) {
EXPECT_FALSE(service()->IsAllowed());
#if defined(GOOGLE_CHROME_BUILD)
EXPECT_FALSE(HasEasyUnlockApp());
#endif
-
- SetEasyUnlockAllowedPolicy(true);
- EXPECT_TRUE(service()->IsAllowed());
-#if defined(GOOGLE_CHROME_BUILD)
- EXPECT_TRUE(HasEasyUnlockApp());
-#endif
}
-class EasyUnlockServiceFinchDisabledTest : public EasyUnlockServiceTest {
- public:
- EasyUnlockServiceFinchDisabledTest() {}
- virtual ~EasyUnlockServiceFinchDisabledTest() {}
-
- // InProcessBrowserTest:
- virtual void SetUpCommandLine(CommandLine* command_line) override {
- command_line->AppendSwitchASCII(switches::kForceFieldTrials,
- "EasyUnlock/Disable/");
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceFinchDisabledTest);
-};
-
-// Tests that easy unlock is off when finch is disabled and policy overrides
-// finch.
-IN_PROC_BROWSER_TEST_F(EasyUnlockServiceFinchDisabledTest, PolicyOverride) {
- // Finch is disabled.
+// Tests that policy does not override disabled switch.
+IN_PROC_BROWSER_TEST_F(EasyUnlockServiceDisabledTest, NoPolicyOverride) {
EXPECT_FALSE(service()->IsAllowed());
#if defined(GOOGLE_CHROME_BUILD)
EXPECT_FALSE(HasEasyUnlockApp());
@@ -244,9 +226,9 @@
// Policy overrides finch and turns on Easy unlock.
SetEasyUnlockAllowedPolicy(true);
- EXPECT_TRUE(service()->IsAllowed());
+ EXPECT_FALSE(service()->IsAllowed());
#if defined(GOOGLE_CHROME_BUILD)
- EXPECT_TRUE(HasEasyUnlockApp());
+ EXPECT_FALSE(HasEasyUnlockApp());
#endif
}
diff --git a/chrome/browser/signin/easy_unlock_service_regular.cc b/chrome/browser/signin/easy_unlock_service_regular.cc
index fb027f3..1eca98e 100644
--- a/chrome/browser/signin/easy_unlock_service_regular.cc
+++ b/chrome/browser/signin/easy_unlock_service_regular.cc
@@ -6,7 +6,6 @@
#include "base/bind.h"
#include "base/logging.h"
-#include "base/metrics/field_trial.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/values.h"
@@ -279,12 +278,6 @@
if (!profile()->GetPrefs()->GetBoolean(prefs::kEasyUnlockAllowed))
return false;
- // Respect existing policy and skip finch test.
- if (!profile()->GetPrefs()->IsManagedPreference(prefs::kEasyUnlockAllowed)) {
- // It is enabled when the trial exists and is in "Enable" group.
- return base::FieldTrialList::FindFullName("EasyUnlock") == "Enable";
- }
-
return true;
#else
// TODO(xiyuan): Revisit when non-chromeos platforms are supported.
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
index ec49823..0a3dd4f 100644
--- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
+++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
@@ -9,6 +9,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/sys_info.h"
#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
@@ -184,7 +185,9 @@
void EasyUnlockServiceSignin::RecordPasswordLoginEvent(
const std::string& user_id) const {
- DCHECK_EQ(GetUserEmail(), user_id);
+ // This happens during tests where user could login without pod focusing.
+ if (GetUserEmail() != user_id)
+ return;
chromeos::EasyUnlockLoginEvent event =
chromeos::EASY_SIGN_IN_LOGIN_EVENT_COUNT;
@@ -310,6 +313,10 @@
}
void EasyUnlockServiceSignin::LoadCurrentUserDataIfNeeded() {
+ // TODO(xiyuan): Revisit this when adding tests.
+ if (!base::SysInfo::IsRunningOnChromeOS())
+ return;
+
if (user_id_.empty() || !service_active_)
return;
diff --git a/chrome/browser/ssl/ssl_client_auth_observer.cc b/chrome/browser/ssl/ssl_client_auth_observer.cc
index edc63bb..46f580e 100644
--- a/chrome/browser/ssl/ssl_client_auth_observer.cc
+++ b/chrome/browser/ssl/ssl_client_auth_observer.cc
@@ -19,10 +19,10 @@
typedef std::pair<net::SSLCertRequestInfo*, net::X509Certificate*> CertDetails;
SSLClientAuthObserver::SSLClientAuthObserver(
- const content::BrowserContext* browser_context,
+ const net::HttpNetworkSession* network_session,
const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback)
- : browser_context_(browser_context),
+ : network_session_(network_session),
cert_request_info_(cert_request_info),
callback_(callback) {
}
@@ -44,7 +44,7 @@
content::NotificationService* service =
content::NotificationService::current();
service->Notify(chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
- content::Source<content::BrowserContext>(browser_context_),
+ content::Source<net::HttpNetworkSession>(network_session_),
content::Details<CertDetails>(&details));
callback_.Run(certificate);
@@ -76,7 +76,7 @@
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
notification_registrar_.Add(
this, chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED,
- content::Source<content::BrowserContext>(browser_context_));
+ content::Source<net::HttpNetworkSession>(network_session_));
}
void SSLClientAuthObserver::StopObserving() {
diff --git a/chrome/browser/ssl/ssl_client_auth_observer.h b/chrome/browser/ssl/ssl_client_auth_observer.h
index 62e3fde..1fe5f39 100644
--- a/chrome/browser/ssl/ssl_client_auth_observer.h
+++ b/chrome/browser/ssl/ssl_client_auth_observer.h
@@ -11,18 +11,15 @@
#include "content/public/browser/notification_registrar.h"
namespace net {
+class HttpNetworkSession;
class SSLCertRequestInfo;
class X509Certificate;
}
-namespace content {
-class BrowserContext;
-}
-
class SSLClientAuthObserver : public content::NotificationObserver {
public:
SSLClientAuthObserver(
- const content::BrowserContext* browser_context,
+ const net::HttpNetworkSession* network_session,
const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback);
~SSLClientAuthObserver() override;
@@ -55,7 +52,7 @@
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
- const content::BrowserContext* browser_context_;
+ const net::HttpNetworkSession* network_session_;
scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
base::Callback<void(net::X509Certificate*)> callback_;
content::NotificationRegistrar notification_registrar_;
diff --git a/chrome/browser/ssl/ssl_client_auth_requestor_mock.cc b/chrome/browser/ssl/ssl_client_auth_requestor_mock.cc
index 6f63c32..78c2c96 100644
--- a/chrome/browser/ssl/ssl_client_auth_requestor_mock.cc
+++ b/chrome/browser/ssl/ssl_client_auth_requestor_mock.cc
@@ -4,13 +4,18 @@
#include "chrome/browser/ssl/ssl_client_auth_requestor_mock.h"
+#include "net/http/http_transaction_factory.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
SSLClientAuthRequestorMock::SSLClientAuthRequestorMock(
net::URLRequest* request,
const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info)
- : cert_request_info_(cert_request_info) {
+ : cert_request_info_(cert_request_info),
+ http_network_session_(request->context()
+ ->http_transaction_factory()
+ ->GetSession()) {
}
SSLClientAuthRequestorMock::~SSLClientAuthRequestorMock() {}
diff --git a/chrome/browser/ssl/ssl_client_auth_requestor_mock.h b/chrome/browser/ssl/ssl_client_auth_requestor_mock.h
index 7d63a7c..69bd729 100644
--- a/chrome/browser/ssl/ssl_client_auth_requestor_mock.h
+++ b/chrome/browser/ssl/ssl_client_auth_requestor_mock.h
@@ -25,6 +25,7 @@
MOCK_METHOD1(CertificateSelected, void(net::X509Certificate* cert));
scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
+ net::HttpNetworkSession* http_network_session_;
protected:
friend class base::RefCountedThreadSafe<SSLClientAuthRequestorMock>;
diff --git a/chrome/browser/ssl/ssl_client_certificate_selector.h b/chrome/browser/ssl/ssl_client_certificate_selector.h
index 1a33c05..afec4ad 100644
--- a/chrome/browser/ssl/ssl_client_certificate_selector.h
+++ b/chrome/browser/ssl/ssl_client_certificate_selector.h
@@ -12,6 +12,7 @@
}
namespace net {
+class HttpNetworkSession;
class SSLCertRequestInfo;
class X509Certificate;
}
@@ -27,6 +28,7 @@
// with a NULL certificate.
void ShowSSLClientCertificateSelector(
content::WebContents* contents,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const SelectCertificateCallback& callback);
diff --git a/chrome/browser/ui/android/ssl_client_certificate_request.cc b/chrome/browser/ui/android/ssl_client_certificate_request.cc
index 65c9ada..afe2d7e 100644
--- a/chrome/browser/ui/android/ssl_client_certificate_request.cc
+++ b/chrome/browser/ui/android/ssl_client_certificate_request.cc
@@ -226,6 +226,7 @@
void ShowSSLClientCertificateSelector(
content::WebContents* contents,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const chrome::SelectCertificateCallback& callback) {
ui::WindowAndroid* window =
diff --git a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
index 514ce33..0a2fda5 100644
--- a/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
+++ b/chrome/browser/ui/cocoa/extensions/browser_actions_container_view.mm
@@ -124,7 +124,7 @@
(NSWidth(containerFrame) < maxWidth_);
// Notify others to see whether this dragging is allowed.
- if (canDragLeft_ || canDragRight_) {
+ if ((dX < 0.0 && canDragLeft_) || (dX > 0.0 && canDragRight_)) {
NSDictionary* userInfo = @{ kTranslationWithDelta : @(dX) };
[[NSNotificationCenter defaultCenter]
postNotificationName:kBrowserActionGrippyWillDragNotification
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h
index aacdafe..991a23a 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.h
@@ -16,10 +16,6 @@
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_sheet_controller.h"
-namespace content {
-class BrowserContext;
-}
-
class ConstrainedWindowMac;
@class SFChooseIdentityPanel;
class SSLClientAuthObserverCocoaBridge;
@@ -45,7 +41,7 @@
@property (readonly, nonatomic) SFChooseIdentityPanel* panel;
-- (id)initWithBrowserContext:(const content::BrowserContext*)browserContext
+- (id)initWithNetworkSession:(const net::HttpNetworkSession*)networkSession
certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo
callback:(const chrome::SelectCertificateCallback&)callback;
- (void)displayForWebContents:(content::WebContents*)webContents;
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
index 9d471b9..027b896 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa.mm
@@ -40,11 +40,11 @@
public ConstrainedWindowMacDelegate {
public:
SSLClientAuthObserverCocoaBridge(
- const content::BrowserContext* browser_context,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const chrome::SelectCertificateCallback& callback,
SSLClientCertificateSelectorCocoa* controller)
- : SSLClientAuthObserver(browser_context, cert_request_info, callback),
+ : SSLClientAuthObserver(network_session, cert_request_info, callback),
controller_(controller) {
}
@@ -71,13 +71,14 @@
void ShowSSLClientCertificateSelector(
content::WebContents* contents,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const SelectCertificateCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The dialog manages its own lifetime.
SSLClientCertificateSelectorCocoa* selector =
[[SSLClientCertificateSelectorCocoa alloc]
- initWithBrowserContext:contents->GetBrowserContext()
+ initWithNetworkSession:network_session
certRequestInfo:cert_request_info
callback:callback];
[selector displayForWebContents:contents];
@@ -87,14 +88,14 @@
@implementation SSLClientCertificateSelectorCocoa
-- (id)initWithBrowserContext:(const content::BrowserContext*)browserContext
+- (id)initWithNetworkSession:(const net::HttpNetworkSession*)networkSession
certRequestInfo:(net::SSLCertRequestInfo*)certRequestInfo
callback:(const chrome::SelectCertificateCallback&)callback {
- DCHECK(browserContext);
+ DCHECK(networkSession);
DCHECK(certRequestInfo);
if ((self = [super init])) {
observer_.reset(new SSLClientAuthObserverCocoaBridge(
- browserContext, certRequestInfo, callback, self));
+ networkSession, certRequestInfo, callback, self));
}
return self;
}
diff --git a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm
index a0c7110..37757d6 100644
--- a/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/ssl_client_certificate_selector_cocoa_browsertest.mm
@@ -50,7 +50,7 @@
int count = 0;
SSLClientCertificateSelectorCocoa* selector =
[[SSLClientCertificateSelectorCocoa alloc]
- initWithBrowserContext:web_contents->GetBrowserContext()
+ initWithNetworkSession:auth_requestor_->http_network_session_
certRequestInfo:auth_requestor_->cert_request_info_.get()
callback:base::Bind(&OnCertificateSelected,
&cert,
@@ -72,13 +72,13 @@
// Test that switching to another tab correctly hides the sheet.
IN_PROC_BROWSER_TEST_F(SSLClientCertificateSelectorCocoaTest, HideShow) {
- content::WebContents* web_contents =
- browser()->tab_strip_model()->GetActiveWebContents();
SSLClientCertificateSelectorCocoa* selector =
[[SSLClientCertificateSelectorCocoa alloc]
- initWithBrowserContext:web_contents->GetBrowserContext()
+ initWithNetworkSession:auth_requestor_->http_network_session_
certRequestInfo:auth_requestor_->cert_request_info_.get()
callback:chrome::SelectCertificateCallback()];
+ content::WebContents* web_contents =
+ browser()->tab_strip_model()->GetActiveWebContents();
[selector displayForWebContents:web_contents];
content::RunAllPendingInMessageLoop();
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
index 5ec6011..f9bf819 100644
--- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
+++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.cc
@@ -309,6 +309,10 @@
browser_->host_desktop_type(), disposition);
}
}
+ UMA_HISTOGRAM_TIMES("WrenchMenu.TimeToAction.RecentTab",
+ menu_opened_timer_.Elapsed());
+ UMA_HISTOGRAM_ENUMERATION("WrenchMenu.MenuAction", MENU_ACTION_RECENT_TAB,
+ LIMIT_MENU_ACTION);
}
int RecentTabsSubMenuModel::GetFirstRecentTabsCommandId() {
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h
index b1eb408..34ba9fd 100644
--- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h
+++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h
@@ -9,6 +9,7 @@
#include "base/memory/weak_ptr.h"
#include "base/task/cancelable_task_tracker.h"
+#include "base/timer/elapsed_timer.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/sessions/tab_restore_service_observer.h"
@@ -168,6 +169,9 @@
base::WeakPtrFactory<RecentTabsSubMenuModel> weak_ptr_factory_;
+ // Time the menu is open for until a recent tab is selected.
+ base::ElapsedTimer menu_opened_timer_;
+
DISALLOW_COPY_AND_ASSIGN(RecentTabsSubMenuModel);
};
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model.cc b/chrome/browser/ui/toolbar/wrench_menu_model.cc
index cedb297..44a73e7 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model.cc
+++ b/chrome/browser/ui/toolbar/wrench_menu_model.cc
@@ -8,6 +8,7 @@
#include <cmath>
#include "base/command_line.h"
+#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
@@ -276,6 +277,7 @@
WrenchMenuModel::WrenchMenuModel(ui::AcceleratorProvider* provider,
Browser* browser)
: ui::SimpleMenuModel(this),
+ uma_action_recorded_(false),
provider_(provider),
browser_(browser),
tab_strip_model_(browser_->tab_strip_model()) {
@@ -404,17 +406,307 @@
}
}
- if (command_id == IDC_HELP_PAGE_VIA_MENU)
- content::RecordAction(UserMetricsAction("ShowHelpTabViaWrenchMenu"));
+ LogMenuMetrics(command_id);
+ chrome::ExecuteCommand(browser_, command_id);
+}
- if (command_id == IDC_FULLSCREEN) {
- // We issue the UMA command here and not in BrowserCommandController or even
- // FullscreenController since we want to be able to distinguish this event
- // and a menu which is under development.
- content::RecordAction(UserMetricsAction("EnterFullScreenWithWrenchMenu"));
+void WrenchMenuModel::LogMenuMetrics(int command_id) {
+ base::TimeDelta delta = timer_.Elapsed();
+
+ switch (command_id) {
+ case IDC_NEW_TAB:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.NewTab", delta);
+ LogMenuAction(MENU_ACTION_NEW_TAB);
+ break;
+ case IDC_NEW_WINDOW:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.NewWindow", delta);
+ LogMenuAction(MENU_ACTION_NEW_WINDOW);
+ break;
+ case IDC_NEW_INCOGNITO_WINDOW:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.NewIncognitoWindow",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_NEW_INCOGNITO_WINDOW);
+ break;
+
+ // Bookmarks sub menu.
+ case IDC_SHOW_BOOKMARK_BAR:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowBookmarkBar",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_SHOW_BOOKMARK_BAR);
+ break;
+ case IDC_SHOW_BOOKMARK_MANAGER:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowBookmarkMgr",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_SHOW_BOOKMARK_MANAGER);
+ break;
+ case IDC_IMPORT_SETTINGS:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ImportSettings",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_IMPORT_SETTINGS);
+ break;
+ case IDC_BOOKMARK_PAGE:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.BookmarkPage",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_BOOKMARK_PAGE);
+ break;
+ case IDC_BOOKMARK_ALL_TABS:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.BookmarkAllTabs",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_BOOKMARK_ALL_TABS);
+ break;
+ case IDC_PIN_TO_START_SCREEN:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.PinToStartScreen",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_PIN_TO_START_SCREEN);
+ break;
+
+ // Recent tabs menu.
+ case IDC_RESTORE_TAB:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.RestoreTab", delta);
+ LogMenuAction(MENU_ACTION_RESTORE_TAB);
+ break;
+
+ // Windows.
+ case IDC_WIN_DESKTOP_RESTART:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.WinDesktopRestart",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_WIN_DESKTOP_RESTART);
+ break;
+ case IDC_WIN8_METRO_RESTART:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Win8MetroRestart",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_WIN8_METRO_RESTART);
+ break;
+
+ case IDC_WIN_CHROMEOS_RESTART:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ChromeOSRestart",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_WIN_CHROMEOS_RESTART);
+ break;
+ case IDC_DISTILL_PAGE:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DistillPage",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_DISTILL_PAGE);
+ break;
+ case IDC_SAVE_PAGE:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.SavePage", delta);
+ LogMenuAction(MENU_ACTION_SAVE_PAGE);
+ break;
+ case IDC_FIND:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Find", delta);
+ LogMenuAction(MENU_ACTION_FIND);
+ break;
+ case IDC_PRINT:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Print", delta);
+ LogMenuAction(MENU_ACTION_PRINT);
+ break;
+
+ // Edit menu.
+ case IDC_CUT:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Cut", delta);
+ LogMenuAction(MENU_ACTION_CUT);
+ break;
+ case IDC_COPY:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Copy", delta);
+ LogMenuAction(MENU_ACTION_COPY);
+ break;
+ case IDC_PASTE:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Paste", delta);
+ LogMenuAction(MENU_ACTION_PASTE);
+ break;
+
+ // Tools menu.
+ case IDC_CREATE_HOSTED_APP:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.CreateHostedApp",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_CREATE_HOSTED_APP);
+ break;
+ case IDC_CREATE_SHORTCUTS:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.CreateShortcuts",
+ delta);
+ LogMenuAction(MENU_ACTION_CREATE_SHORTCUTS);
+ break;
+ case IDC_MANAGE_EXTENSIONS:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ManageExtensions",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_MANAGE_EXTENSIONS);
+ break;
+ case IDC_TASK_MANAGER:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.TaskManager",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_TASK_MANAGER);
+ break;
+ case IDC_CLEAR_BROWSING_DATA:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ClearBrowsingData",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_CLEAR_BROWSING_DATA);
+ break;
+ case IDC_VIEW_SOURCE:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ViewSource", delta);
+ LogMenuAction(MENU_ACTION_VIEW_SOURCE);
+ break;
+ case IDC_DEV_TOOLS:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DevTools", delta);
+ LogMenuAction(MENU_ACTION_DEV_TOOLS);
+ break;
+ case IDC_DEV_TOOLS_CONSOLE:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DevToolsConsole",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_DEV_TOOLS_CONSOLE);
+ break;
+ case IDC_DEV_TOOLS_DEVICES:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DevToolsDevices",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_DEV_TOOLS_DEVICES);
+ break;
+ case IDC_PROFILING_ENABLED:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ProfilingEnabled",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_PROFILING_ENABLED);
+ break;
+
+ // Zoom menu
+ case IDC_ZOOM_MINUS:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ZoomMinus", delta);
+ LogMenuAction(MENU_ACTION_ZOOM_MINUS);
+ }
+ break;
+ case IDC_ZOOM_PLUS:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ZoomPlus", delta);
+ LogMenuAction(MENU_ACTION_ZOOM_PLUS);
+ }
+ break;
+ case IDC_FULLSCREEN:
+ content::RecordAction(UserMetricsAction("EnterFullScreenWithWrenchMenu"));
+
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.EnterFullScreen",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_FULLSCREEN);
+ break;
+
+ case IDC_SHOW_HISTORY:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowHistory",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_SHOW_HISTORY);
+ break;
+ case IDC_SHOW_DOWNLOADS:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowDownloads",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_SHOW_DOWNLOADS);
+ break;
+ case IDC_SHOW_SYNC_SETUP:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowSyncSetup",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_SHOW_SYNC_SETUP);
+ break;
+ case IDC_OPTIONS:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Settings", delta);
+ LogMenuAction(MENU_ACTION_OPTIONS);
+ break;
+ case IDC_ABOUT:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.About", delta);
+ LogMenuAction(MENU_ACTION_ABOUT);
+ break;
+
+ // Help menu.
+ case IDC_HELP_PAGE_VIA_MENU:
+ content::RecordAction(UserMetricsAction("ShowHelpTabViaWrenchMenu"));
+
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.HelpPage", delta);
+ LogMenuAction(MENU_ACTION_HELP_PAGE_VIA_MENU);
+ break;
+ #if defined(GOOGLE_CHROME_BUILD)
+ case IDC_FEEDBACK:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Feedback", delta);
+ LogMenuAction(MENU_ACTION_FEEDBACK);
+ break;
+ #endif
+
+ case IDC_TOGGLE_REQUEST_TABLET_SITE:
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.RequestTabletSite",
+ delta);
+ }
+ LogMenuAction(MENU_ACTION_TOGGLE_REQUEST_TABLET_SITE);
+ break;
+ case IDC_EXIT:
+ if (!uma_action_recorded_)
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Exit", delta);
+ LogMenuAction(MENU_ACTION_EXIT);
+ break;
}
- chrome::ExecuteCommand(browser_, command_id);
+ if (!uma_action_recorded_) {
+ UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction", delta);
+ uma_action_recorded_ = true;
+ }
+}
+
+void WrenchMenuModel::LogMenuAction(int action_id) {
+ UMA_HISTOGRAM_ENUMERATION("WrenchMenu.MenuAction", action_id,
+ LIMIT_MENU_ACTION);
}
bool WrenchMenuModel::IsCommandIdChecked(int command_id) const {
@@ -665,6 +957,7 @@
}
RemoveTrailingSeparators();
+ uma_action_recorded_ = false;
}
void WrenchMenuModel::AddGlobalErrorMenuItems() {
diff --git a/chrome/browser/ui/toolbar/wrench_menu_model.h b/chrome/browser/ui/toolbar/wrench_menu_model.h
index ff787c8..4b9cefe 100644
--- a/chrome/browser/ui/toolbar/wrench_menu_model.h
+++ b/chrome/browser/ui/toolbar/wrench_menu_model.h
@@ -7,6 +7,8 @@
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "content/public/browser/host_zoom_map.h"
#include "content/public/browser/notification_observer.h"
@@ -24,6 +26,54 @@
class MockWrenchMenuModel;
} // namespace
+enum WrenchMenuAction {
+ MENU_ACTION_NEW_TAB = 0,
+ MENU_ACTION_NEW_WINDOW,
+ MENU_ACTION_NEW_INCOGNITO_WINDOW,
+ MENU_ACTION_SHOW_BOOKMARK_BAR,
+ MENU_ACTION_SHOW_BOOKMARK_MANAGER,
+ MENU_ACTION_IMPORT_SETTINGS,
+ MENU_ACTION_BOOKMARK_PAGE,
+ MENU_ACTION_BOOKMARK_ALL_TABS,
+ MENU_ACTION_PIN_TO_START_SCREEN,
+ MENU_ACTION_RESTORE_TAB,
+ MENU_ACTION_WIN_DESKTOP_RESTART,
+ MENU_ACTION_WIN8_METRO_RESTART,
+ MENU_ACTION_WIN_CHROMEOS_RESTART,
+ MENU_ACTION_DISTILL_PAGE,
+ MENU_ACTION_SAVE_PAGE,
+ MENU_ACTION_FIND,
+ MENU_ACTION_PRINT,
+ MENU_ACTION_CUT,
+ MENU_ACTION_COPY,
+ MENU_ACTION_PASTE,
+ MENU_ACTION_CREATE_HOSTED_APP,
+ MENU_ACTION_CREATE_SHORTCUTS,
+ MENU_ACTION_MANAGE_EXTENSIONS,
+ MENU_ACTION_TASK_MANAGER,
+ MENU_ACTION_CLEAR_BROWSING_DATA,
+ MENU_ACTION_VIEW_SOURCE,
+ MENU_ACTION_DEV_TOOLS,
+ MENU_ACTION_DEV_TOOLS_CONSOLE,
+ MENU_ACTION_DEV_TOOLS_DEVICES,
+ MENU_ACTION_PROFILING_ENABLED,
+ MENU_ACTION_ZOOM_MINUS,
+ MENU_ACTION_ZOOM_PLUS,
+ MENU_ACTION_FULLSCREEN,
+ MENU_ACTION_SHOW_HISTORY,
+ MENU_ACTION_SHOW_DOWNLOADS,
+ MENU_ACTION_SHOW_SYNC_SETUP,
+ MENU_ACTION_OPTIONS,
+ MENU_ACTION_ABOUT,
+ MENU_ACTION_HELP_PAGE_VIA_MENU,
+ MENU_ACTION_FEEDBACK,
+ MENU_ACTION_TOGGLE_REQUEST_TABLET_SITE,
+ MENU_ACTION_EXIT,
+ MENU_ACTION_RECENT_TAB,
+ MENU_ACTION_BOOKMARK_OPEN,
+ LIMIT_MENU_ACTION
+};
+
// A menu model that builds the contents of an encoding menu.
class EncodingMenuModel : public ui::SimpleMenuModel,
public ui::SimpleMenuModel::Delegate {
@@ -157,6 +207,23 @@
bool ShouldShowNewIncognitoWindowMenuItem();
+ // Called when a command is selected.
+ // Logs UMA metrics about which command was chosen and how long the user
+ // took to select the command.
+ void LogMenuMetrics(int command_id);
+
+ // Helper function to record the menu action in a UMA histogram.
+ void LogMenuAction(int action_id);
+
+ // Time menu has been open. Used by LogMenuMetrics() to record the time
+ // to action when the user selects a menu item.
+ base::ElapsedTimer timer_;
+
+ // Whether a UMA menu action has been recorded since the menu is open.
+ // Only the first time to action is recorded since some commands
+ // (zoom controls) don't dimiss the menu.
+ bool uma_action_recorded_;
+
// Models for the special menu items with buttons.
scoped_ptr<ui::ButtonMenuItemModel> edit_menu_item_model_;
scoped_ptr<ui::ButtonMenuItemModel> zoom_menu_item_model_;
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
index 969de17..0a03027 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
@@ -82,10 +82,10 @@
SSLClientCertificateSelector::SSLClientCertificateSelector(
content::WebContents* web_contents,
+ const net::HttpNetworkSession* network_session,
const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info,
const chrome::SelectCertificateCallback& callback)
- : SSLClientAuthObserver(web_contents->GetBrowserContext(),
- cert_request_info, callback),
+ : SSLClientAuthObserver(network_session, cert_request_info, callback),
model_(new CertificateSelectorTableModel(cert_request_info.get())),
web_contents_(web_contents),
table_(NULL),
@@ -274,12 +274,13 @@
void ShowSSLClientCertificateSelector(
content::WebContents* contents,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const chrome::SelectCertificateCallback& callback) {
DVLOG(1) << __FUNCTION__ << " " << contents;
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
(new SSLClientCertificateSelector(
- contents, cert_request_info, callback))->Init();
+ contents, network_session, cert_request_info, callback))->Init();
}
} // namespace chrome
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.h b/chrome/browser/ui/views/ssl_client_certificate_selector.h
index de4fbed..882b4b0 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector.h
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector.h
@@ -40,6 +40,7 @@
public:
SSLClientCertificateSelector(
content::WebContents* web_contents,
+ const net::HttpNetworkSession* network_session,
const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info,
const chrome::SelectCertificateCallback& callback);
~SSLClientCertificateSelector() override;
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc b/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc
index 390abd4..b5dba23 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector_browsertest.cc
@@ -73,6 +73,7 @@
browser()->tab_strip_model()->GetActiveWebContents());
selector_ = new SSLClientCertificateSelector(
browser()->tab_strip_model()->GetActiveWebContents(),
+ auth_requestor_->http_network_session_,
auth_requestor_->cert_request_info_,
base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
auth_requestor_));
@@ -160,12 +161,14 @@
selector_1_ = new SSLClientCertificateSelector(
browser()->tab_strip_model()->GetWebContentsAt(1),
+ auth_requestor_1_->http_network_session_,
auth_requestor_1_->cert_request_info_,
base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
auth_requestor_1_));
selector_1_->Init();
selector_2_ = new SSLClientCertificateSelector(
browser()->tab_strip_model()->GetWebContentsAt(2),
+ auth_requestor_2_->http_network_session_,
auth_requestor_2_->cert_request_info_,
base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
auth_requestor_2_));
@@ -236,6 +239,7 @@
selector_1_ = new SSLClientCertificateSelector(
browser_1_->tab_strip_model()->GetActiveWebContents(),
+ auth_requestor_1_->http_network_session_,
auth_requestor_1_->cert_request_info_,
base::Bind(&SSLClientAuthRequestorMock::CertificateSelected,
auth_requestor_1_));
diff --git a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
index b882cc5..50dc01f 100644
--- a/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
+++ b/chrome/browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views.cc
@@ -153,9 +153,6 @@
const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
#if defined(USE_AURA)
- if (!browser_defaults::kShowLinkDisambiguationPopup)
- return;
-
link_disambiguation_popup_.reset(new LinkDisambiguationPopup);
link_disambiguation_popup_->Show(
views::Widget::GetTopLevelWidgetForNativeView(GetActiveNativeView()),
diff --git a/chrome/browser/ui/views/toolbar/wrench_menu.cc b/chrome/browser/ui/views/toolbar/wrench_menu.cc
index 8c1d8d2..f057fb5 100644
--- a/chrome/browser/ui/views/toolbar/wrench_menu.cc
+++ b/chrome/browser/ui/views/toolbar/wrench_menu.cc
@@ -8,6 +8,7 @@
#include <cmath>
#include <set>
+#include "base/metrics/histogram.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
@@ -1001,6 +1002,10 @@
void WrenchMenu::ExecuteCommand(int command_id, int mouse_event_flags) {
if (IsBookmarkCommand(command_id)) {
+ UMA_HISTOGRAM_TIMES("WrenchMenu.TimeToAction.BookmarkOpen",
+ menu_opened_timer_.Elapsed());
+ UMA_HISTOGRAM_ENUMERATION("WrenchMenu.MenuAction",
+ MENU_ACTION_BOOKMARK_OPEN, LIMIT_MENU_ACTION);
bookmark_menu_delegate_->ExecuteCommand(command_id, mouse_event_flags);
return;
}
diff --git a/chrome/browser/ui/views/toolbar/wrench_menu.h b/chrome/browser/ui/views/toolbar/wrench_menu.h
index 267f1de..6dfbe1a 100644
--- a/chrome/browser/ui/views/toolbar/wrench_menu.h
+++ b/chrome/browser/ui/views/toolbar/wrench_menu.h
@@ -10,6 +10,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
+#include "base/time/time.h"
+#include "base/timer/elapsed_timer.h"
#include "components/bookmarks/browser/base_bookmark_model_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
@@ -184,6 +186,9 @@
ObserverList<WrenchMenuObserver> observer_list_;
+ // Records the time from when menu opens to when the user selects a menu item.
+ base::ElapsedTimer menu_opened_timer_;
+
DISALLOW_COPY_AND_ASSIGN(WrenchMenu);
};
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 9e3ac1c..368fb5e 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -13,6 +13,8 @@
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen_actor.h"
#include "chrome/browser/chromeos/login/enrollment/enrollment_screen_actor.h"
+#include "chrome/browser/chromeos/login/screens/error_screen.h"
+#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/consumer_management_service.h"
#include "chrome/browser/chromeos/system/input_device_settings.h"
@@ -273,6 +275,15 @@
error_screen_handler_ = new ErrorScreenHandler(network_state_informer_);
AddScreenHandler(error_screen_handler_);
+ // Initialize ErrorScreen if it hasn't initialized.
+ if (WizardController::default_controller()) {
+ BaseScreen* screen = WizardController::default_controller()->GetScreen(
+ WizardController::kErrorScreenName);
+ CHECK(screen);
+ } else {
+ error_screen_.reset(new ErrorScreen(nullptr, error_screen_handler_));
+ }
+
EnrollmentScreenHandler* enrollment_screen_handler =
new EnrollmentScreenHandler(network_state_informer_,
error_screen_handler_);
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
index ee73c32..1e34272 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/chromeos/login/ui/oobe_display.h"
#include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
@@ -25,7 +26,9 @@
class BaseScreenHandler;
class ControllerPairingScreenActor;
class DeviceDisabledScreenActor;
+class ErrorScreen;
class ErrorScreenHandler;
+class GaiaScreenHandler;
class HostPairingScreenActor;
class KioskAppMenuHandler;
class KioskEnableScreenActor;
@@ -33,7 +36,6 @@
class NativeWindowDelegate;
class NetworkDropdownHandler;
class NetworkStateInformer;
-class GaiaScreenHandler;
class SigninScreenHandler;
class SigninScreenHandlerDelegate;
class UpdateScreenHandler;
@@ -221,6 +223,8 @@
KioskAppMenuHandler* kiosk_app_menu_handler_; // Non-owning pointers.
+ scoped_ptr<ErrorScreen> error_screen_;
+
// Id of the current oobe/login screen.
Screen current_screen_;
diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc
index 8883413..2bcd470 100644
--- a/chrome/installer/util/google_update_settings.cc
+++ b/chrome/installer/util/google_update_settings.cc
@@ -64,45 +64,49 @@
return true;
}
-// Updates a registry key |name| to be |value| for the given |app_reg_data|.
-// If this is a |system_install|, then update the value under HKLM (istead of
-// HKCU for user-installs) using a group of keys (one for each OS user) and also
-// include the method to |aggregate| these values when reporting.
-bool WriteGoogleUpdateStrKeyInternal(const AppRegistrationData& app_reg_data,
- bool system_install,
- const wchar_t* const name,
- const base::string16& value,
- const wchar_t* const aggregate) {
+// Writes |value| into a user-specific value in the key |name| under
+// |app_reg_data|'s ClientStateMedium key in HKLM along with the aggregation
+// method |aggregate|. This function is solely for use by system-level installs.
+bool WriteGoogleUpdateAggregateNumKeyInternal(
+ const AppRegistrationData& app_reg_data,
+ const wchar_t* const name,
+ int value,
+ const wchar_t* const aggregate) {
+ DCHECK(aggregate);
+ DCHECK(GoogleUpdateSettings::IsSystemInstall());
const REGSAM kAccess = KEY_SET_VALUE | KEY_WOW64_32KEY;
- if (system_install) {
- DCHECK(aggregate);
- // Machine installs require each OS user to write a unique key under a
- // named key in HKLM as well as an "aggregation" function that describes
- // how the values of multiple users are to be combined.
- base::string16 uniquename;
- if (!base::win::GetUserSidString(&uniquename)) {
- NOTREACHED();
- return false;
- }
- base::string16 reg_path(app_reg_data.GetStateMediumKey());
- reg_path.append(L"\\");
- reg_path.append(name);
- RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), kAccess);
- key.WriteValue(google_update::kRegAggregateMethod, aggregate);
- return (key.WriteValue(uniquename.c_str(), value.c_str()) == ERROR_SUCCESS);
- } else {
- // User installs are easy: just write the values to HKCU tree.
- RegKey key(HKEY_CURRENT_USER, app_reg_data.GetStateKey().c_str(), kAccess);
- return (key.WriteValue(name, value.c_str()) == ERROR_SUCCESS);
+ // Machine installs require each OS user to write a unique key under a
+ // named key in HKLM as well as an "aggregation" function that describes
+ // how the values of multiple users are to be combined.
+ base::string16 uniquename;
+ if (!base::win::GetUserSidString(&uniquename)) {
+ NOTREACHED();
+ return false;
}
+
+ base::string16 reg_path(app_reg_data.GetStateMediumKey());
+ reg_path.append(L"\\");
+ reg_path.append(name);
+ RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), kAccess);
+ key.WriteValue(google_update::kRegAggregateMethod, aggregate);
+ return (key.WriteValue(uniquename.c_str(), value) == ERROR_SUCCESS);
+}
+
+// Updates a registry key |name| to be |value| for the given |app_reg_data|.
+bool WriteGoogleUpdateStrKeyInternal(const AppRegistrationData& app_reg_data,
+ const wchar_t* const name,
+ const base::string16& value) {
+ const REGSAM kAccess = KEY_SET_VALUE | KEY_WOW64_32KEY;
+ RegKey key(HKEY_CURRENT_USER, app_reg_data.GetStateKey().c_str(), kAccess);
+ return (key.WriteValue(name, value.c_str()) == ERROR_SUCCESS);
}
bool WriteGoogleUpdateStrKey(const wchar_t* const name,
const base::string16& value) {
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
return WriteGoogleUpdateStrKeyInternal(
- dist->GetAppRegistrationData(), false, name, value, NULL);
+ dist->GetAppRegistrationData(), name, value);
}
bool ClearGoogleUpdateStrKey(const wchar_t* const name) {
@@ -434,10 +438,8 @@
const AppRegistrationData& app_reg_data,
bool did_run) {
return WriteGoogleUpdateStrKeyInternal(app_reg_data,
- false, // user level.
google_update::kRegDidRunField,
- did_run ? L"1" : L"0",
- NULL);
+ did_run ? L"1" : L"0");
}
bool GoogleUpdateSettings::UpdateDidRunState(bool did_run, bool system_level) {
@@ -547,17 +549,31 @@
void GoogleUpdateSettings::UpdateProfileCounts(int profiles_active,
int profiles_signedin) {
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- bool system_install = IsSystemInstall();
- WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(),
- system_install,
- google_update::kRegProfilesActive,
- base::Int64ToString16(profiles_active),
- L"sum()");
- WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(),
- system_install,
- google_update::kRegProfilesSignedIn,
- base::Int64ToString16(profiles_signedin),
- L"sum()");
+ // System-level installs must write into the ClientStateMedium key shared by
+ // all users. Special treatment is used to aggregate across those users.
+ if (IsSystemInstall()) {
+ // Write the counts as ints that get aggregated across all users via
+ // summation for system-level installs.
+ WriteGoogleUpdateAggregateNumKeyInternal(
+ dist->GetAppRegistrationData(),
+ google_update::kRegProfilesActive,
+ profiles_active,
+ L"sum()");
+ WriteGoogleUpdateAggregateNumKeyInternal(
+ dist->GetAppRegistrationData(),
+ google_update::kRegProfilesSignedIn,
+ profiles_signedin,
+ L"sum()");
+ } else {
+ // Write the counts as strings since no aggregation function is needed for
+ // user-level installs.
+ WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(),
+ google_update::kRegProfilesActive,
+ base::IntToString16(profiles_active));
+ WriteGoogleUpdateStrKeyInternal(dist->GetAppRegistrationData(),
+ google_update::kRegProfilesSignedIn,
+ base::IntToString16(profiles_signedin));
+ }
}
int GoogleUpdateSettings::DuplicateGoogleUpdateSystemClientKey() {
diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc
index ecab320..3e7943f 100644
--- a/chrome/installer/util/google_update_settings_unittest.cc
+++ b/chrome/installer/util/google_update_settings_unittest.cc
@@ -8,10 +8,14 @@
#include <shlwapi.h> // For SHDeleteKey.
#include "base/memory/scoped_ptr.h"
+#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_path_override.h"
#include "base/test/test_reg_util_win.h"
#include "base/win/registry.h"
+#include "base/win/win_util.h"
#include "chrome/common/chrome_constants.h"
+#include "chrome/installer/util/app_registration_data.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/channel_info.h"
#include "chrome/installer/util/fake_installation_state.h"
@@ -35,6 +39,11 @@
class GoogleUpdateSettingsTest : public testing::Test {
protected:
virtual void SetUp() override {
+ base::FilePath program_files_path;
+ PathService::Get(base::DIR_PROGRAM_FILES, &program_files_path);
+ program_files_override_.reset(new base::ScopedPathOverride(
+ base::DIR_PROGRAM_FILES, program_files_path));
+
registry_overrides_.OverrideRegistry(HKEY_LOCAL_MACHINE);
registry_overrides_.OverrideRegistry(HKEY_CURRENT_USER);
}
@@ -297,6 +306,8 @@
time_in_minutes) == ERROR_SUCCESS;
}
+ // Keep Program Files path so InstallUtil::IsPerUserInstall doesn't crash.
+ scoped_ptr<base::ScopedPathOverride> program_files_override_;
registry_util::RegistryOverrideManager registry_overrides_;
};
@@ -628,6 +639,113 @@
EXPECT_FALSE(is_overridden);
}
+TEST_F(GoogleUpdateSettingsTest, UpdateProfileCountsSystemInstall) {
+ // Pretend to be a system install for GoogleUpdateSettings::IsSystemInstall().
+ base::FilePath program_files_path;
+ PathService::Get(base::DIR_PROGRAM_FILES, &program_files_path);
+ base::ScopedPathOverride dir_module_override(base::DIR_MODULE,
+ program_files_path);
+
+ // No profile count keys present yet.
+ const base::string16& state_key = BrowserDistribution::GetDistribution()->
+ GetAppRegistrationData().GetStateMediumKey();
+ base::string16 num_profiles_path(state_key);
+ num_profiles_path.append(L"\\");
+ num_profiles_path.append(google_update::kRegProfilesActive);
+ base::string16 num_signed_in_path(state_key);
+ num_signed_in_path.append(L"\\");
+ num_signed_in_path.append(google_update::kRegProfilesSignedIn);
+
+ EXPECT_EQ(ERROR_FILE_NOT_FOUND,
+ RegKey().Open(HKEY_LOCAL_MACHINE,
+ num_profiles_path.c_str(),
+ KEY_QUERY_VALUE));
+ EXPECT_EQ(ERROR_FILE_NOT_FOUND,
+ RegKey().Open(HKEY_LOCAL_MACHINE,
+ num_signed_in_path.c_str(),
+ KEY_QUERY_VALUE));
+
+ // Show time! Write the values.
+ GoogleUpdateSettings::UpdateProfileCounts(3, 2);
+
+ // Verify the keys were created.
+ EXPECT_EQ(ERROR_SUCCESS,
+ RegKey().Open(HKEY_LOCAL_MACHINE,
+ num_profiles_path.c_str(),
+ KEY_QUERY_VALUE));
+ EXPECT_EQ(ERROR_SUCCESS,
+ RegKey().Open(HKEY_LOCAL_MACHINE,
+ num_signed_in_path.c_str(),
+ KEY_QUERY_VALUE));
+
+ base::string16 uniquename;
+ EXPECT_TRUE(base::win::GetUserSidString(&uniquename));
+
+ // Verify the values are accessible.
+ DWORD num_profiles = 0;
+ DWORD num_signed_in = 0;
+ base::string16 aggregate;
+ EXPECT_EQ(
+ ERROR_SUCCESS,
+ RegKey(HKEY_LOCAL_MACHINE, num_profiles_path.c_str(),
+ KEY_QUERY_VALUE).ReadValueDW(uniquename.c_str(),
+ &num_profiles));
+ EXPECT_EQ(
+ ERROR_SUCCESS,
+ RegKey(HKEY_LOCAL_MACHINE, num_signed_in_path.c_str(),
+ KEY_QUERY_VALUE).ReadValueDW(uniquename.c_str(),
+ &num_signed_in));
+ EXPECT_EQ(
+ ERROR_SUCCESS,
+ RegKey(HKEY_LOCAL_MACHINE, num_signed_in_path.c_str(),
+ KEY_QUERY_VALUE).ReadValue(google_update::kRegAggregateMethod,
+ &aggregate));
+
+ // Verify the correct values were written.
+ EXPECT_EQ(3, num_profiles);
+ EXPECT_EQ(2, num_signed_in);
+ EXPECT_EQ(L"sum()", aggregate);
+}
+
+TEST_F(GoogleUpdateSettingsTest, UpdateProfileCountsUserInstall) {
+ // Unit tests never operate as an installed application, so will never
+ // be a system install.
+
+ // No profile count values present yet.
+ const base::string16& state_key = BrowserDistribution::GetDistribution()->
+ GetAppRegistrationData().GetStateKey();
+
+ EXPECT_EQ(ERROR_FILE_NOT_FOUND,
+ RegKey().Open(HKEY_CURRENT_USER,
+ state_key.c_str(),
+ KEY_QUERY_VALUE));
+
+ // Show time! Write the values.
+ GoogleUpdateSettings::UpdateProfileCounts(4, 1);
+
+ // Verify the key was created.
+ EXPECT_EQ(ERROR_SUCCESS,
+ RegKey().Open(HKEY_CURRENT_USER,
+ state_key.c_str(),
+ KEY_QUERY_VALUE));
+
+ // Verify the values are accessible.
+ base::string16 num_profiles;
+ base::string16 num_signed_in;
+ EXPECT_EQ(
+ ERROR_SUCCESS,
+ RegKey(HKEY_CURRENT_USER, state_key.c_str(), KEY_QUERY_VALUE).
+ ReadValue(google_update::kRegProfilesActive, &num_profiles));
+ EXPECT_EQ(
+ ERROR_SUCCESS,
+ RegKey(HKEY_CURRENT_USER, state_key.c_str(), KEY_QUERY_VALUE).
+ ReadValue(google_update::kRegProfilesSignedIn, &num_signed_in));
+
+ // Verify the correct values were written.
+ EXPECT_EQ(L"4", num_profiles);
+ EXPECT_EQ(L"1", num_signed_in);
+}
+
#if defined(GOOGLE_CHROME_BUILD)
// Test that the default override is returned if no app-specific override is
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index c6b3a5a..dd95406 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -37,9 +37,6 @@
// Disables the ChromeOS demo.
const char kDisableDemoMode[] = "disable-demo-mode";
-// Disable Easy sign-in.
-const char kDisableEasySignin[] = "disable-easy-signin";
-
// Disable HID-detection OOBE screen.
const char kDisableHIDDetectionOnOOBE[] = "disable-hid-detection-on-oobe";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h
index 049c1dc..bec2bca 100644
--- a/chromeos/chromeos_switches.h
+++ b/chromeos/chromeos_switches.h
@@ -31,7 +31,6 @@
CHROMEOS_EXPORT extern const char kDisableBootAnimation[];
CHROMEOS_EXPORT extern const char kDisableDemoMode[];
CHROMEOS_EXPORT extern const char kDisableDeviceDisabling[];
-CHROMEOS_EXPORT extern const char kDisableEasySignin[];
CHROMEOS_EXPORT extern const char kDisableGaiaServices[];
CHROMEOS_EXPORT extern const char kDisableHIDDetectionOnOOBE[];
CHROMEOS_EXPORT extern const char kDisableLoginAnimations[];
diff --git a/components/autofill/core/common/password_form.cc b/components/autofill/core/common/password_form.cc
index 0f3ee64..69c3200 100644
--- a/components/autofill/core/common/password_form.cc
+++ b/components/autofill/core/common/password_form.cc
@@ -5,6 +5,7 @@
#include <ostream>
#include "base/strings/string16.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/common/password_form.h"
@@ -73,6 +74,8 @@
<< base::UTF16ToUTF8(form.new_password_element)
<< " new_password_value: "
<< base::UTF16ToUTF8(form.new_password_value)
+ << " other_possible_usernames: "
+ << JoinString(form.other_possible_usernames, '|')
<< " autocomplete_set:" << form.password_autocomplete_set
<< " blacklisted: " << form.blacklisted_by_user
<< " preferred: " << form.preferred
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
index 125d8ac..6ce7f7b 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.cc
@@ -40,7 +40,7 @@
return nullptr;
DataReductionProxyBypassType bypass_type = BYPASS_EVENT_TYPE_MAX;
bool should_retry = data_reduction_proxy::MaybeBypassProxyAndPrepareToRetry(
- params_, request, request->response_info().headers.get(), &bypass_type);
+ params_, request, &bypass_type);
if (usage_stats_ && bypass_type != BYPASS_EVENT_TYPE_MAX)
usage_stats_->SetBypassType(bypass_type);
if (!should_retry)
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc
index 17b3f80..876cb2e 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.cc
@@ -43,10 +43,14 @@
bool MaybeBypassProxyAndPrepareToRetry(
const DataReductionProxyParams* data_reduction_proxy_params,
net::URLRequest* request,
- const net::HttpResponseHeaders* original_response_headers,
DataReductionProxyBypassType* proxy_bypass_type) {
+ DCHECK(request);
if (!data_reduction_proxy_params)
return false;
+ const net::HttpResponseHeaders* response_headers =
+ request->response_info().headers.get();
+ if (!response_headers)
+ return false;
DataReductionProxyTypeInfo data_reduction_proxy_type_info;
if (!data_reduction_proxy_params->WasDataReductionProxyUsed(
request, &data_reduction_proxy_type_info)) {
@@ -68,15 +72,15 @@
// via header, so detect and report cases where the via header is missing.
DataReductionProxyUsageStats::DetectAndRecordMissingViaHeaderResponseCode(
!data_reduction_proxy_type_info.proxy_servers.second.is_empty(),
- original_response_headers);
+ response_headers);
DataReductionProxyTamperDetection::DetectAndReport(
- original_response_headers,
+ response_headers,
data_reduction_proxy_type_info.proxy_servers.first.SchemeIsSecure());
DataReductionProxyInfo data_reduction_proxy_info;
DataReductionProxyBypassType bypass_type =
- GetDataReductionProxyBypassType(original_response_headers,
+ GetDataReductionProxyBypassType(response_headers,
&data_reduction_proxy_info);
if (bypass_type == BYPASS_EVENT_TYPE_MISSING_VIA_HEADER_OTHER &&
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.h
index 13aae29..faf7729 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol.h
@@ -34,7 +34,6 @@
bool MaybeBypassProxyAndPrepareToRetry(
const DataReductionProxyParams* params,
net::URLRequest* request,
- const net::HttpResponseHeaders* original_response_headers,
DataReductionProxyBypassType* proxy_bypass_type);
// Adds data reduction proxies to |result|, where applicable, if result
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
index 3625d60..c61b4f7 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_protocol_unittest.cc
@@ -123,19 +123,10 @@
// if |expect_response_body|.
void TestProxyFallback(const char* method,
const char* first_response,
- bool has_origin,
bool expected_retry,
+ bool generate_response_error,
size_t expected_bad_proxy_count,
bool expect_response_body) {
- std::string payload1 =
- (expected_retry ? "Bypass message" : "content");
- MockRead data_reads[] = {
- MockRead(first_response),
- MockRead(payload1.c_str()),
- MockRead(net::SYNCHRONOUS, net::OK),
- };
- std::string origin = has_origin ? "Origin: foo.com\r\n" : "";
-
std::string m(method);
std::string trailer =
(m == "HEAD" || m == "PUT" || m == "POST") ?
@@ -144,56 +135,78 @@
std::string request1 =
base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n"
"Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n%s%s"
+ "Proxy-Connection: keep-alive\r\n%s"
"User-Agent:\r\n"
"Accept-Encoding: gzip, deflate\r\n\r\n",
- method, origin.c_str(), trailer.c_str());
+ method, trailer.c_str());
+
+ std::string payload1 =
+ (expected_retry ? "Bypass message" : "content");
+
MockWrite data_writes[] = {
MockWrite(request1.c_str()),
};
+
+ MockRead data_reads[] = {
+ MockRead(first_response),
+ MockRead(payload1.c_str()),
+ MockRead(net::SYNCHRONOUS, net::OK),
+ };
+ MockRead data_reads_error[] = {
+ MockRead(net::SYNCHRONOUS, net::ERR_INVALID_RESPONSE),
+ };
+
StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
data_writes, arraysize(data_writes));
- mock_socket_factory_.AddSocketDataProvider(&data1);
+ StaticSocketDataProvider data1_error(data_reads_error,
+ arraysize(data_reads_error),
+ data_writes, arraysize(data_writes));
+ if (!generate_response_error)
+ mock_socket_factory_.AddSocketDataProvider(&data1);
+ else
+ mock_socket_factory_.AddSocketDataProvider(&data1_error);
- std::string response2;
- std::string request2;
- if (expected_bad_proxy_count >= 2u ||
- (m != "POST" && expected_retry && expected_bad_proxy_count == 0u)) {
- response2 =
- "HTTP/1.0 200 OK\r\n"
- "Server: not-proxy\r\n\r\n";
- request2 = base::StringPrintf(
- "%s / HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Connection: keep-alive\r\n%s%s"
- "User-Agent:\r\n"
- "Accept-Encoding: gzip, deflate\r\n\r\n",
- method, origin.c_str(), trailer.c_str());
- } else if (expected_bad_proxy_count <= 1u) {
- response2 =
- "HTTP/1.0 200 OK\r\n"
- "Server: not-proxy\r\n"
- "Via: 1.1 Chrome-Compression-Proxy\r\n\r\n";
- request2 = base::StringPrintf(
- "%s http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n%s%s"
- "User-Agent:\r\n"
- "Accept-Encoding: gzip, deflate\r\n\r\n",
- method, origin.c_str(), trailer.c_str());
- }
- MockRead data_reads2[] = {
- MockRead(response2.c_str()),
- MockRead("content"),
- MockRead(net::SYNCHRONOUS, net::OK),
- };
- MockWrite data_writes2[] = {
- MockWrite(request2.c_str()),
- };
- StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
- data_writes2, arraysize(data_writes2));
- if (expected_retry) {
- mock_socket_factory_.AddSocketDataProvider(&data2);
+ std::string response2;
+ std::string request2;
+ std::string response2_via_header = "";
+ std::string request2_connection_type = "";
+ std::string request2_path = "/";
+ bool idempotent_block_once =
+ m != "POST" && expected_retry && expected_bad_proxy_count == 0u;
+
+ if (expected_bad_proxy_count < 2u && !idempotent_block_once) {
+ request2_path = "http://www.google.com/";
+ request2_connection_type = "Proxy-";
+ response2_via_header = "Via: 1.1 Chrome-Compression-Proxy\r\n";
+ }
+
+ request2 = base::StringPrintf(
+ "%s %s HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "%sConnection: keep-alive\r\n%s"
+ "User-Agent:\r\n"
+ "Accept-Encoding: gzip, deflate\r\n\r\n",
+ method, request2_path.c_str(), request2_connection_type.c_str(),
+ trailer.c_str());
+
+ response2 = base::StringPrintf(
+ "HTTP/1.0 200 OK\r\n"
+ "Server: foo\r\n%s\r\n", response2_via_header.c_str());
+
+ MockWrite data_writes2[] = {
+ MockWrite(request2.c_str()),
+ };
+
+ MockRead data_reads2[] = {
+ MockRead(response2.c_str()),
+ MockRead("content"),
+ MockRead(net::SYNCHRONOUS, net::OK),
+ };
+
+ StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
+ data_writes2, arraysize(data_writes2));
+ if (expected_retry) {
+ mock_socket_factory_.AddSocketDataProvider(&data2);
}
// Expect that we get "content" and not "Bypass message", and that there's
@@ -201,22 +214,16 @@
ExecuteRequestExpectingContentAndHeader(
method,
(expect_response_body ? "content" : ""),
- "server",
- (expected_retry == 0 ? "proxy" : "not-proxy"),
- has_origin,
- expected_retry);
+ expected_retry,
+ generate_response_error);
}
// Starts a request with the given |method| and checks that the response
- // contains |content| and the the header |header|: |value|, if |header| is
- // non-empty. Verifies that the request's URL chain is the right length
- // depending on whether or not a retry was expected (|expected_retry|).
+ // contains |content|.
void ExecuteRequestExpectingContentAndHeader(const std::string& method,
const std::string& content,
- const std::string& header,
- const std::string& value,
- bool has_origin,
- bool expected_retry) {
+ bool expected_retry,
+ bool expected_error) {
TestDelegate d;
scoped_ptr<URLRequest> r(context_->CreateRequest(
GURL("http://www.google.com/"),
@@ -225,25 +232,23 @@
NULL));
r->set_method(method);
r->SetLoadFlags(net::LOAD_NORMAL);
- if (has_origin)
- r->SetExtraRequestHeaderByName("Origin", "foo.com", true);
r->Start();
base::RunLoop().Run();
- EXPECT_EQ(net::URLRequestStatus::SUCCESS, r->status().status());
- EXPECT_EQ(net::OK, r->status().error());
- if (expected_retry)
- EXPECT_EQ(2, network_delegate_->headers_received_count());
- else
- EXPECT_EQ(1, network_delegate_->headers_received_count());
-
- if (!header.empty()) {
- // We also have a server header here that isn't set by the proxy.
- EXPECT_TRUE(r->response_headers()->HasHeaderValue(header, value));
+ if (!expected_error) {
+ EXPECT_EQ(net::URLRequestStatus::SUCCESS, r->status().status());
+ EXPECT_EQ(net::OK, r->status().error());
+ if (expected_retry)
+ EXPECT_EQ(2, network_delegate_->headers_received_count());
+ else
+ EXPECT_EQ(1, network_delegate_->headers_received_count());
+ EXPECT_EQ(content, d.data_received());
+ return;
}
-
- EXPECT_EQ(content, d.data_received());
+ EXPECT_EQ(net::URLRequestStatus::FAILED, r->status().status());
+ EXPECT_EQ(net::ERR_INVALID_RESPONSE, r->status().error());
+ EXPECT_EQ(0, network_delegate_->headers_received_count());
}
// Returns the key to the |ProxyRetryInfoMap|.
@@ -343,8 +348,8 @@
const struct {
const char* method;
const char* first_response;
- bool has_origin;
bool expected_retry;
+ bool generate_response_error;
size_t expected_bad_proxy_count;
bool expect_response_body;
int expected_duration;
@@ -362,6 +367,16 @@
-1,
BYPASS_EVENT_TYPE_MAX,
},
+ // Response error does not result in bypass.
+ { "GET",
+ "Not an HTTP response",
+ false,
+ true,
+ 0u,
+ true,
+ -1,
+ BYPASS_EVENT_TYPE_MAX,
+ },
// Valid data reduction proxy response with older, but still valid via
// header.
{ "GET",
@@ -394,8 +409,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=0\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -407,8 +422,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=1\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
1,
@@ -420,8 +435,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=0\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -433,8 +448,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=0\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
false,
0,
@@ -446,8 +461,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=0\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -459,8 +474,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=0\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -472,8 +487,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=0\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -484,8 +499,8 @@
"HTTP/1.1 500 Internal Server Error\r\n"
"Server: proxy\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -496,8 +511,8 @@
"HTTP/1.1 502 Internal Server Error\r\n"
"Server: proxy\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -508,8 +523,8 @@
"HTTP/1.1 503 Internal Server Error\r\n"
"Server: proxy\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -519,8 +534,8 @@
{ "GET",
"HTTP/1.1 404 Not Found\r\n"
"Server: proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
1,
@@ -530,8 +545,8 @@
{ "GET",
"HTTP/1.1 200 OK\r\n"
"Server: proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -542,8 +557,8 @@
"HTTP/1.1 200 OK\r\n"
"Server: proxy\r\n"
"Via: 1.0 some-other-proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
0,
@@ -581,8 +596,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block=1\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
2u,
true,
1,
@@ -596,8 +611,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
0u,
true,
0,
@@ -609,8 +624,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
0u,
true,
0,
@@ -622,8 +637,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
0u,
false,
0,
@@ -635,8 +650,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
0u,
true,
0,
@@ -648,8 +663,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
0u,
true,
0,
@@ -661,8 +676,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
0u,
true,
0,
@@ -692,8 +707,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: block=1, block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
2u,
true,
1,
@@ -707,8 +722,8 @@
"Server: proxy\r\n"
"Chrome-Proxy: bypass=1, block-once\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n\r\n",
- false,
true,
+ false,
1u,
true,
1,
@@ -726,8 +741,8 @@
&bypass_type);
TestProxyFallback(tests[i].method,
tests[i].first_response,
- tests[i].has_origin,
tests[i].expected_retry,
+ tests[i].generate_response_error,
tests[i].expected_bad_proxy_count,
tests[i].expect_response_body);
EXPECT_EQ(tests[i].expected_bypass_type, usage_stats_->GetBypassType());
diff --git a/components/data_reduction_proxy_version_header.target.darwin-arm.mk b/components/data_reduction_proxy_version_header.target.darwin-arm.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-arm.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-arm.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-arm64.mk b/components/data_reduction_proxy_version_header.target.darwin-arm64.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-arm64.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-arm64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-mips.mk b/components/data_reduction_proxy_version_header.target.darwin-mips.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-mips.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-mips.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-mips64.mk b/components/data_reduction_proxy_version_header.target.darwin-mips64.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-mips64.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-mips64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-x86.mk b/components/data_reduction_proxy_version_header.target.darwin-x86.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-x86.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-x86.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk b/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk
+++ b/components/data_reduction_proxy_version_header.target.darwin-x86_64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-arm.mk b/components/data_reduction_proxy_version_header.target.linux-arm.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.linux-arm.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-arm.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-arm64.mk b/components/data_reduction_proxy_version_header.target.linux-arm64.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.linux-arm64.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-arm64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-mips.mk b/components/data_reduction_proxy_version_header.target.linux-mips.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.linux-mips.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-mips.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-mips64.mk b/components/data_reduction_proxy_version_header.target.linux-mips64.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.linux-mips64.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-mips64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-x86.mk b/components/data_reduction_proxy_version_header.target.linux-x86.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.linux-x86.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-x86.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/data_reduction_proxy_version_header.target.linux-x86_64.mk b/components/data_reduction_proxy_version_header.target.linux-x86_64.mk
index 3167295..de8667a 100644
--- a/components/data_reduction_proxy_version_header.target.linux-x86_64.mk
+++ b/components/data_reduction_proxy_version_header.target.linux-x86_64.mk
@@ -22,7 +22,7 @@
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h: $(LOCAL_PATH)/chrome/VERSION $(LOCAL_PATH)/components/data_reduction_proxy/core/common/version.h.in $(GYP_TARGET_DEPENDENCIES)
@echo "Gyp action: Generating version header file: "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h" ($@)"
- $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.27\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
+ $(hide)cd $(gyp_local_path)/components; mkdir -p $(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common; python ../build/util/version.py -e "VERSION_FULL=\"40.0.2214.38\"" data_reduction_proxy/core/common/version.h.in "$(gyp_shared_intermediate_dir)/components/data_reduction_proxy/core/common/version.h"
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index 60fa6fd..0570e74 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -648,9 +648,10 @@
std::string registered_domain = GetRegistryControlledDomain(signon_realm);
PSLDomainMatchMetric psl_domain_match_metric = PSL_DOMAIN_MATCH_NONE;
const bool should_PSL_matching_apply =
+ form.scheme == PasswordForm::SCHEME_HTML &&
ShouldPSLDomainMatchingApply(registered_domain);
// PSL matching only applies to HTML forms.
- if (form.scheme == PasswordForm::SCHEME_HTML && should_PSL_matching_apply) {
+ if (should_PSL_matching_apply) {
// We are extending the original SQL query with one that includes more
// possible matches based on public suffix domain matching. Using a regexp
// here is just an optimization to not have to parse all the stored entries
diff --git a/components/password_manager/core/browser/login_database_unittest.cc b/components/password_manager/core/browser/login_database_unittest.cc
index 5ec0e2e..f3a27f8 100644
--- a/components/password_manager/core/browser/login_database_unittest.cc
+++ b/components/password_manager/core/browser/login_database_unittest.cc
@@ -102,7 +102,7 @@
EXPECT_TRUE(db_.GetLogins(second_non_html_auth, &result.get()));
EXPECT_EQ(0U, result.size());
- // non-html auth still matches again itself.
+ // non-html auth still matches against itself.
EXPECT_TRUE(db_.GetLogins(non_html_auth, &result.get()));
ASSERT_EQ(1U, result.size());
EXPECT_EQ(result[0]->signon_realm, "http://example.com/Realm");
@@ -111,6 +111,32 @@
db_.RemoveLoginsCreatedBetween(now, base::Time());
}
+ // Checks that a form of a given |scheme|, once stored, can be successfully
+ // retrieved from the database.
+ void TestRetrievingIPAddress(const PasswordForm::Scheme& scheme) {
+ SCOPED_TRACE(testing::Message() << "scheme = " << scheme);
+ ScopedVector<PasswordForm> result;
+
+ base::Time now = base::Time::Now();
+ std::string origin("http://56.7.8.90");
+
+ PasswordForm ip_form;
+ ip_form.origin = GURL(origin);
+ ip_form.username_value = ASCIIToUTF16("test@gmail.com");
+ ip_form.password_value = ASCIIToUTF16("test");
+ ip_form.signon_realm = origin;
+ ip_form.scheme = scheme;
+ ip_form.date_created = now;
+
+ EXPECT_EQ(AddChangeForForm(ip_form), db_.AddLogin(ip_form));
+ EXPECT_TRUE(db_.GetLogins(ip_form, &result.get()));
+ ASSERT_EQ(1U, result.size());
+ EXPECT_EQ(result[0]->signon_realm, origin);
+
+ // Clear state.
+ db_.RemoveLoginsCreatedBetween(now, base::Time());
+ }
+
base::ScopedTempDir temp_dir_;
base::FilePath file_;
LoginDatabase db_;
@@ -315,6 +341,22 @@
TestNonHTMLFormPSLMatching(PasswordForm::SCHEME_OTHER);
}
+TEST_F(LoginDatabaseTest, TestIPAddressMatches_HTML) {
+ TestRetrievingIPAddress(PasswordForm::SCHEME_HTML);
+}
+
+TEST_F(LoginDatabaseTest, TestIPAddressMatches_basic) {
+ TestRetrievingIPAddress(PasswordForm::SCHEME_BASIC);
+}
+
+TEST_F(LoginDatabaseTest, TestIPAddressMatches_digest) {
+ TestRetrievingIPAddress(PasswordForm::SCHEME_DIGEST);
+}
+
+TEST_F(LoginDatabaseTest, TestIPAddressMatches_other) {
+ TestRetrievingIPAddress(PasswordForm::SCHEME_OTHER);
+}
+
TEST_F(LoginDatabaseTest, TestPublicSuffixDomainMatchingShouldMatchingApply) {
std::vector<PasswordForm*> result;
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 4dd75b5..b4c2e22 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -257,6 +257,17 @@
is_new_login_ = true;
user_action_ = password_changed ? kUserActionChoosePslMatch
: kUserActionOverridePassword;
+
+ // Update credential to reflect that it has been used for submission.
+ // If this isn't updated, then password generation uploads are off for
+ // sites where PSL matching is required to fill the login form, as two
+ // PASSWORD votes are uploaded per saved password instead of one.
+ //
+ // TODO(gcasto): It would be nice if other state were shared such that if
+ // say a password was updated on one match it would update on all related
+ // passwords. This is a much larger change.
+ UpdateMetadataForUsage(pending_credentials_);
+
// Normally, the copy of the PSL matched credentials, adapted for the
// current domain, is saved automatically without asking the user, because
// the copy likely represents the same account, i.e., the one for which
@@ -543,9 +554,15 @@
// Upload credentials the first time they are saved. This data is used
// by password generation to help determine account creation sites.
// Blacklisted credentials will never be used, so don't upload a vote for
- // them.
- if (!pending_credentials_.blacklisted_by_user)
- UploadPasswordForm(pending_credentials_.form_data, autofill::PASSWORD);
+ // them. Credentials that have been previously used (e.g. PSL matches) are
+ // checked to see if they are valid account creation forms.
+ if (!pending_credentials_.blacklisted_by_user) {
+ if (pending_credentials_.times_used == 0) {
+ UploadPasswordForm(pending_credentials_.form_data, autofill::PASSWORD);
+ } else {
+ CheckForAccountCreationForm(pending_credentials_, observed_form_);
+ }
+ }
pending_credentials_.date_created = Time::Now();
SanitizePossibleUsernames(&pending_credentials_);
@@ -604,8 +621,7 @@
return;
}
- // Update metadata.
- ++pending_credentials_.times_used;
+ UpdateMetadataForUsage(pending_credentials_);
if (client_->IsSyncAccountCredential(
base::UTF16ToUTF8(pending_credentials_.username_value),
@@ -619,10 +635,6 @@
UpdatePreferredLoginState(password_store);
- // Remove alternate usernames. At this point we assume that we have found
- // the right username.
- pending_credentials_.other_possible_usernames.clear();
-
// Update the new preferred login.
if (!selected_username_.empty()) {
// An other possible username is selected. We set this selected username
@@ -675,6 +687,15 @@
}
}
+void PasswordFormManager::UpdateMetadataForUsage(
+ const PasswordForm& credential) {
+ ++pending_credentials_.times_used;
+
+ // Remove alternate usernames. At this point we assume that we have found
+ // the right username.
+ pending_credentials_.other_possible_usernames.clear();
+}
+
bool PasswordFormManager::UpdatePendingCredentialsIfOtherPossibleUsername(
const base::string16& username) {
for (PasswordFormMap::const_iterator it = best_matches_.begin();
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index 67ac2ea..3037ce6 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -254,6 +254,10 @@
bool UpdatePendingCredentialsIfOtherPossibleUsername(
const base::string16& username);
+ // Update state to reflect that |credential| was used. This is broken out from
+ // UpdateLogin() so that PSL matches can also be properly updated.
+ void UpdateMetadataForUsage(const autofill::PasswordForm& credential);
+
// Converts the "ActionsTaken" fields into an int so they can be logged to
// UMA.
int GetActionsTaken();
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index c38ed9a..f81bfbd 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -34,6 +34,7 @@
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
+using ::testing::SaveArg;
namespace password_manager {
@@ -170,6 +171,22 @@
saved_match_.other_possible_usernames.push_back(
ASCIIToUTF16("test2@gmail.com"));
+ autofill::FormFieldData field;
+ field.label = ASCIIToUTF16("full_name");
+ field.name = ASCIIToUTF16("full_name");
+ field.form_control_type = "text";
+ saved_match_.form_data.fields.push_back(field);
+
+ field.label = ASCIIToUTF16("Email");
+ field.name = ASCIIToUTF16("Email");
+ field.form_control_type = "text";
+ saved_match_.form_data.fields.push_back(field);
+
+ field.label = ASCIIToUTF16("password");
+ field.name = ASCIIToUTF16("password");
+ field.form_control_type = "password";
+ saved_match_.form_data.fields.push_back(field);
+
mock_store_ = new NiceMock<MockPasswordStore>();
client_.reset(new TestPasswordManagerClient(mock_store_.get()));
}
@@ -321,6 +338,48 @@
EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch());
}
+TEST_F(PasswordFormManagerTest, PSLMatchedCredentialsMetadataUpdated) {
+ TestPasswordManagerClient client_with_store(mock_store());
+ EXPECT_CALL(*(client_with_store.mock_driver()), IsOffTheRecord())
+ .WillRepeatedly(Return(false));
+
+ TestPasswordManager manager(&client_with_store);
+ PasswordFormManager form_manager(&manager,
+ &client_with_store,
+ client_with_store.mock_driver(),
+ *observed_form(),
+ false);
+
+ // The suggestion needs to be PSL-matched.
+ saved_match()->original_signon_realm = "www.example.org";
+ SimulateMatchingPhase(&form_manager, RESULT_MATCH_FOUND);
+
+ PasswordForm submitted_form(*observed_form());
+ submitted_form.preferred = true;
+ submitted_form.username_value = saved_match()->username_value;
+ submitted_form.password_value = saved_match()->password_value;
+ submitted_form.origin = saved_match()->origin;
+ form_manager.ProvisionallySave(
+ submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
+
+ PasswordForm expected_saved_form(submitted_form);
+ expected_saved_form.times_used = 1;
+ expected_saved_form.other_possible_usernames.clear();
+ expected_saved_form.form_data = saved_match()->form_data;
+ PasswordForm actual_saved_form;
+
+ EXPECT_CALL(*(client_with_store.mock_driver()->mock_autofill_manager()),
+ UploadPasswordForm(_, autofill::ACCOUNT_CREATION_PASSWORD))
+ .Times(1);
+ EXPECT_CALL(*mock_store(), AddLogin(_))
+ .WillOnce(SaveArg<0>(&actual_saved_form));
+ form_manager.Save();
+
+ // Can't verify time, so ignore it.
+ actual_saved_form.date_created = base::Time();
+ EXPECT_EQ(expected_saved_form, actual_saved_form);
+}
+
TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
// Add a new password field to the test form. The PasswordFormManager should
// save the password from this field, instead of the current password field.
@@ -1132,33 +1191,15 @@
EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
.WillRepeatedly(Return(false));
- PasswordForm form(*observed_form());
-
- autofill::FormFieldData field;
- field.label = ASCIIToUTF16("full_name");
- field.name = ASCIIToUTF16("full_name");
- field.form_control_type = "text";
- form.form_data.fields.push_back(field);
-
- field.label = ASCIIToUTF16("Email");
- field.name = ASCIIToUTF16("Email");
- field.form_control_type = "text";
- form.form_data.fields.push_back(field);
-
- field.label = ASCIIToUTF16("password");
- field.name = ASCIIToUTF16("password");
- field.form_control_type = "password";
- form.form_data.fields.push_back(field);
-
// For newly saved passwords, upload a vote for autofill::PASSWORD.
PasswordFormManager form_manager(&password_manager,
&client_with_store,
client_with_store.GetDriver(),
- form,
+ *saved_match(),
false);
SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
- PasswordForm form_to_save(form);
+ PasswordForm form_to_save(*saved_match());
form_to_save.preferred = true;
form_to_save.username_value = ASCIIToUTF16("username");
form_to_save.password_value = ASCIIToUTF16("1234");
@@ -1175,7 +1216,7 @@
PasswordFormManager blacklist_form_manager(&password_manager,
&client_with_store,
client_with_store.GetDriver(),
- form,
+ *saved_match(),
false);
SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH);
diff --git a/components/password_manager/core/browser/psl_matching_helper.cc b/components/password_manager/core/browser/psl_matching_helper.cc
index 69244fa..dd5a1a7 100644
--- a/components/password_manager/core/browser/psl_matching_helper.cc
+++ b/components/password_manager/core/browser/psl_matching_helper.cc
@@ -18,7 +18,8 @@
bool ShouldPSLDomainMatchingApply(
const std::string& registry_controlled_domain) {
- return registry_controlled_domain != "google.com";
+ return !registry_controlled_domain.empty() &&
+ registry_controlled_domain != "google.com";
}
bool IsPublicSuffixDomainMatch(const std::string& url1,
@@ -29,6 +30,9 @@
if (!gurl1.is_valid() || !gurl2.is_valid())
return false;
+ if (gurl1 == gurl2)
+ return true;
+
return gurl1.scheme() == gurl2.scheme() &&
GetRegistryControlledDomain(gurl1) ==
GetRegistryControlledDomain(gurl2) &&
diff --git a/components/proximity_auth/switches.cc b/components/proximity_auth/switches.cc
index ba5aab7..7472761 100644
--- a/components/proximity_auth/switches.cc
+++ b/components/proximity_auth/switches.cc
@@ -7,6 +7,12 @@
namespace proximity_auth {
namespace switches {
+// Disable Easy sign-in.
+const char kDisableEasySignin[] = "disable-easy-signin";
+
+// Disable Easy unlock.
+const char kDisableEasyUnlock[] = "disable-easy-unlock";
+
// Enables close proximity detection. This allows the user to set a setting to
// require very close proximity between the remote device and the local device
// in order to unlock the local device, which trades off convenience for
diff --git a/components/proximity_auth/switches.h b/components/proximity_auth/switches.h
index 0e8fed7..9995e3e 100644
--- a/components/proximity_auth/switches.h
+++ b/components/proximity_auth/switches.h
@@ -10,6 +10,8 @@
// All switches in alphabetical order. The switches should be documented
// alongside the definition of their values in the .cc file.
+extern const char kDisableEasySignin[];
+extern const char kDisableEasyUnlock[];
extern const char kEnableProximityDetection[];
} // namespace switches
diff --git a/content/browser/android/content_startup_flags.cc b/content/browser/android/content_startup_flags.cc
index d531dbb..7fb2b42 100644
--- a/content/browser/android/content_startup_flags.cc
+++ b/content/browser/android/content_startup_flags.cc
@@ -65,7 +65,6 @@
parsed_command_line->AppendSwitch(switches::kInProcessGPU);
parsed_command_line->AppendSwitch(switches::kDisableGpuShaderDiskCache);
- parsed_command_line->AppendSwitch(switches::kEnableViewport);
parsed_command_line->AppendSwitch(switches::kEnableViewportMeta);
parsed_command_line->AppendSwitch(
switches::kMainFrameResizesAreOrientationChanges);
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 12117bf..f9f0f4f 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -249,9 +249,9 @@
BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product);
web_contents->SetUserAgentOverride(spoofed_ua);
- java_bridge_dispatcher_host_.reset(
+ java_bridge_dispatcher_host_ =
new GinJavaBridgeDispatcherHost(web_contents,
- java_bridge_retained_object_set));
+ java_bridge_retained_object_set);
InitWebContents();
}
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 8a823ee..f37659c 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -341,8 +341,7 @@
bool accessibility_enabled_;
// Manages injecting Java objects.
- scoped_ptr<GinJavaBridgeDispatcherHost>
- java_bridge_dispatcher_host_;
+ scoped_refptr<GinJavaBridgeDispatcherHost> java_bridge_dispatcher_host_;
DISALLOW_COPY_AND_ASSIGN(ContentViewCoreImpl);
};
diff --git a/content/browser/android/java/gin_java_bound_object.cc b/content/browser/android/java/gin_java_bound_object.cc
index 99c8b5d..527fcef 100644
--- a/content/browser/android/java/gin_java_bound_object.cc
+++ b/content/browser/android/java/gin_java_bound_object.cc
@@ -42,8 +42,8 @@
GinJavaBoundObject* GinJavaBoundObject::CreateTransient(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- RenderFrameHost* holder) {
- std::set<RenderFrameHost*> holders;
+ int32 holder) {
+ std::set<int32> holders;
holders.insert(holder);
return new GinJavaBoundObject(ref, safe_annotation_clazz, holders);
}
@@ -61,7 +61,7 @@
GinJavaBoundObject::GinJavaBoundObject(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- const std::set<RenderFrameHost*> holders)
+ const std::set<int32>& holders)
: ref_(ref),
names_count_(0),
holders_(holders),
diff --git a/content/browser/android/java/gin_java_bound_object.h b/content/browser/android/java/gin_java_bound_object.h
index ce1d403..72fa7c6 100644
--- a/content/browser/android/java/gin_java_bound_object.h
+++ b/content/browser/android/java/gin_java_bound_object.h
@@ -10,26 +10,17 @@
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
-#include "base/id_map.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
#include "base/values.h"
#include "content/browser/android/java/java_method.h"
namespace content {
-class RenderFrameHost;
-
class GinJavaBoundObject
: public base::RefCountedThreadSafe<GinJavaBoundObject> {
public:
- // Using scoped_refptr<> as a value type is somewhat not IDMap had been
- // designed for (it returns T* from lookups, so we have to de-ref it), but on
- // the other hand, this allows us to manage lifetime of GinJavaBoundObject
- // automatically.
- typedef IDMap<scoped_refptr<GinJavaBoundObject>, IDMapOwnPointer> ObjectMap;
- typedef ObjectMap::KeyType ObjectID;
+ typedef int32 ObjectID;
static GinJavaBoundObject* CreateNamed(
const JavaObjectWeakGlobalRef& ref,
@@ -37,8 +28,9 @@
static GinJavaBoundObject* CreateTransient(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- RenderFrameHost* holder);
+ int32 holder);
+ // The following methods can be called on any thread.
JavaObjectWeakGlobalRef& GetWeakRef() { return ref_; }
base::android::ScopedJavaLocalRef<jobject> GetLocalRef(JNIEnv* env) {
return ref_.get(env);
@@ -49,8 +41,8 @@
void RemoveName() { --names_count_; }
bool HasHolders() { return !holders_.empty(); }
- void AddHolder(RenderFrameHost* holder) { holders_.insert(holder); }
- void RemoveHolder(RenderFrameHost* holder) { holders_.erase(holder); }
+ void AddHolder(int32 holder) { holders_.insert(holder); }
+ void RemoveHolder(int32 holder) { holders_.erase(holder); }
// The following methods are called on the background thread.
std::set<std::string> GetMethodNames();
@@ -70,7 +62,7 @@
GinJavaBoundObject(
const JavaObjectWeakGlobalRef& ref,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
- const std::set<RenderFrameHost*> holders);
+ const std::set<int32>& holders);
~GinJavaBoundObject();
// The following methods are called on the background thread.
@@ -81,7 +73,7 @@
// An object must be kept in retained_object_set_ either if it has
// names or if it has a non-empty holders set.
int names_count_;
- std::set<RenderFrameHost*> holders_;
+ std::set<int32> holders_;
// The following fields are accessed on the background thread.
typedef std::multimap<std::string, linked_ptr<JavaMethod> > JavaMethodMap;
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index c0b20b9..7255920 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -7,7 +7,9 @@
#include "base/android/java_handler_thread.h"
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
+#include "base/atomic_sequence_num.h"
#include "base/lazy_instance.h"
+#include "base/pickle.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
@@ -18,6 +20,7 @@
#include "content/common/gin_java_bridge_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_utils.h"
@@ -38,29 +41,63 @@
virtual ~JavaBridgeThread() {
Stop();
}
+ static bool CurrentlyOn();
};
base::LazyInstance<JavaBridgeThread> g_background_thread =
LAZY_INSTANCE_INITIALIZER;
+// static
+bool JavaBridgeThread::CurrentlyOn() {
+ return base::MessageLoop::current() ==
+ g_background_thread.Get().message_loop();
+}
+
+// Object IDs are globally unique, so we can figure out the right
+// GinJavaBridgeDispatcherHost when dispatching messages on the background
+// thread.
+base::StaticAtomicSequenceNumber g_next_object_id;
+
} // namespace
GinJavaBridgeDispatcherHost::GinJavaBridgeDispatcherHost(
WebContents* web_contents,
jobject retained_object_set)
: WebContentsObserver(web_contents),
+ BrowserMessageFilter(GinJavaBridgeMsgStart),
+ browser_filter_added_(false),
retained_object_set_(base::android::AttachCurrentThread(),
retained_object_set),
- allow_object_contents_inspection_(true) {
+ allow_object_contents_inspection_(true),
+ current_routing_id_(MSG_ROUTING_NONE) {
DCHECK(retained_object_set);
}
GinJavaBridgeDispatcherHost::~GinJavaBridgeDispatcherHost() {
- DCHECK(pending_replies_.empty());
+}
+
+// GinJavaBridgeDispatcherHost gets created earlier than RenderProcessHost
+// is initialized. So we postpone installing the message filter until we know
+// that the RPH is in a good shape. Currently this means that we are calling
+// this function from any UI thread function that is about to communicate
+// with the renderer.
+// TODO(mnaganov): Redesign, so we only have a single filter for all hosts.
+void GinJavaBridgeDispatcherHost::AddBrowserFilterIfNeeded() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Transient objects can only appear after named objects were added. Thus,
+ // we can wait until we have one, to avoid installing unnecessary filters.
+ if (!browser_filter_added_ &&
+ web_contents()->GetRenderProcessHost()->GetChannel() &&
+ !named_objects_.empty()) {
+ web_contents()->GetRenderProcessHost()->AddFilter(this);
+ browser_filter_added_ = true;
+ }
}
void GinJavaBridgeDispatcherHost::RenderFrameCreated(
RenderFrameHost* render_frame_host) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ AddBrowserFilterIfNeeded();
for (NamedObjectMap::const_iterator iter = named_objects_.begin();
iter != named_objects_.end();
++iter) {
@@ -72,35 +109,40 @@
void GinJavaBridgeDispatcherHost::RenderFrameDeleted(
RenderFrameHost* render_frame_host) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- IPC::Message* reply_msg = TakePendingReply(render_frame_host);
- if (reply_msg != NULL) {
- base::ListValue result;
- result.Append(base::Value::CreateNullValue());
- IPC::WriteParam(reply_msg, result);
- IPC::WriteParam(reply_msg, kGinJavaBridgeRenderFrameDeleted);
- render_frame_host->Send(reply_msg);
+ AddBrowserFilterIfNeeded();
+ base::AutoLock locker(objects_lock_);
+ auto iter = objects_.begin();
+ while (iter != objects_.end()) {
+ JavaObjectWeakGlobalRef ref =
+ RemoveHolderAndAdvanceLocked(render_frame_host->GetRoutingID(), &iter);
+ if (!ref.is_empty()) {
+ RemoveFromRetainedObjectSetLocked(ref);
+ }
}
- RemoveHolder(render_frame_host,
- GinJavaBoundObject::ObjectMap::iterator(&objects_),
- objects_.size());
}
GinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject(
const base::android::JavaRef<jobject>& object,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
bool is_named,
- RenderFrameHost* holder) {
+ int32 holder) {
+ // Can be called on any thread. Calls come from the UI thread via
+ // AddNamedObject, and from the background thread, when injected Java
+ // object's method returns a Java object.
DCHECK(is_named || holder);
- GinJavaBoundObject::ObjectID object_id;
JNIEnv* env = base::android::AttachCurrentThread();
JavaObjectWeakGlobalRef ref(env, object.obj());
- if (is_named) {
- object_id = objects_.Add(new scoped_refptr<GinJavaBoundObject>(
- GinJavaBoundObject::CreateNamed(ref, safe_annotation_clazz)));
- } else {
- object_id = objects_.Add(new scoped_refptr<GinJavaBoundObject>(
- GinJavaBoundObject::CreateTransient(
- ref, safe_annotation_clazz, holder)));
+ scoped_refptr<GinJavaBoundObject> new_object =
+ is_named ? GinJavaBoundObject::CreateNamed(ref, safe_annotation_clazz)
+ : GinJavaBoundObject::CreateTransient(ref, safe_annotation_clazz,
+ holder);
+ // Note that we are abusing the fact that StaticAtomicSequenceNumber
+ // uses Atomic32 as a counter, so it is guaranteed that it will not
+ // overflow our int32 IDs. IDs start from 1.
+ GinJavaBoundObject::ObjectID object_id = g_next_object_id.GetNext() + 1;
+ {
+ base::AutoLock locker(objects_lock_);
+ objects_[object_id] = new_object;
}
#if DCHECK_IS_ON
{
@@ -112,6 +154,7 @@
base::android::ScopedJavaLocalRef<jobject> retained_object_set =
retained_object_set_.get(env);
if (!retained_object_set.is_null()) {
+ base::AutoLock locker(objects_lock_);
JNI_Java_HashSet_add(env, retained_object_set, object);
}
return object_id;
@@ -120,13 +163,14 @@
bool GinJavaBridgeDispatcherHost::FindObjectId(
const base::android::JavaRef<jobject>& object,
GinJavaBoundObject::ObjectID* object_id) {
+ // Can be called on any thread.
JNIEnv* env = base::android::AttachCurrentThread();
- for (GinJavaBoundObject::ObjectMap::iterator it(&objects_); !it.IsAtEnd();
- it.Advance()) {
+ base::AutoLock locker(objects_lock_);
+ for (const auto& pair : objects_) {
if (env->IsSameObject(
object.obj(),
- it.GetCurrentValue()->get()->GetLocalRef(env).obj())) {
- *object_id = it.GetCurrentKey();
+ pair.second->GetLocalRef(env).obj())) {
+ *object_id = pair.first;
return true;
}
}
@@ -135,36 +179,40 @@
JavaObjectWeakGlobalRef GinJavaBridgeDispatcherHost::GetObjectWeakRef(
GinJavaBoundObject::ObjectID object_id) {
- scoped_refptr<GinJavaBoundObject>* result = objects_.Lookup(object_id);
- scoped_refptr<GinJavaBoundObject> object(result ? *result : NULL);
+ scoped_refptr<GinJavaBoundObject> object = FindObject(object_id);
if (object.get())
return object->GetWeakRef();
else
return JavaObjectWeakGlobalRef();
}
-void GinJavaBridgeDispatcherHost::RemoveHolder(
- RenderFrameHost* holder,
- const GinJavaBoundObject::ObjectMap::iterator& from,
- size_t count) {
+JavaObjectWeakGlobalRef
+GinJavaBridgeDispatcherHost::RemoveHolderAndAdvanceLocked(
+ int32 holder,
+ ObjectMap::iterator* iter_ptr) {
+ objects_lock_.AssertAcquired();
+ JavaObjectWeakGlobalRef result;
+ scoped_refptr<GinJavaBoundObject> object((*iter_ptr)->second);
+ if (!object->IsNamed()) {
+ object->RemoveHolder(holder);
+ if (!object->HasHolders()) {
+ result = object->GetWeakRef();
+ objects_.erase((*iter_ptr)++);
+ }
+ } else {
+ ++(*iter_ptr);
+ }
+ return result;
+}
+
+void GinJavaBridgeDispatcherHost::RemoveFromRetainedObjectSetLocked(
+ const JavaObjectWeakGlobalRef& ref) {
+ objects_lock_.AssertAcquired();
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> retained_object_set =
retained_object_set_.get(env);
- size_t i = 0;
- for (GinJavaBoundObject::ObjectMap::iterator it(from);
- !it.IsAtEnd() && i < count;
- it.Advance(), ++i) {
- scoped_refptr<GinJavaBoundObject> object(*it.GetCurrentValue());
- if (object->IsNamed())
- continue;
- object->RemoveHolder(holder);
- if (!object->HasHolders()) {
- if (!retained_object_set.is_null()) {
- JNI_Java_HashSet_remove(
- env, retained_object_set, object->GetLocalRef(env));
- }
- objects_.Remove(it.GetCurrentKey());
- }
+ if (!retained_object_set.is_null()) {
+ JNI_Java_HashSet_remove(env, retained_object_set, ref.get(env));
}
}
@@ -185,12 +233,14 @@
RemoveNamedObject(iter->first);
}
if (existing_object) {
- (*objects_.Lookup(object_id))->AddName();
+ base::AutoLock locker(objects_lock_);
+ objects_[object_id]->AddName();
} else {
- object_id = AddObject(object, safe_annotation_clazz, true, NULL);
+ object_id = AddObject(object, safe_annotation_clazz, true, 0);
}
named_objects_[name] = object_id;
+ AddBrowserFilterIfNeeded();
web_contents()->SendToAllFrames(
new GinJavaBridgeMsg_AddNamedObject(MSG_ROUTING_NONE, name, object_id));
}
@@ -206,28 +256,30 @@
// |name| is from |named_objects_| it'll be valid after the remove below.
const std::string copied_name(name);
- scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(iter->second));
- named_objects_.erase(iter);
- object->RemoveName();
-
- // Not erasing from the objects map, as we can still receive method
- // invocation requests for this object, and they should work until the
- // java object is gone.
- if (!object->IsNamed()) {
- JNIEnv* env = base::android::AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jobject> retained_object_set =
- retained_object_set_.get(env);
- if (!retained_object_set.is_null()) {
- JNI_Java_HashSet_remove(
- env, retained_object_set, object->GetLocalRef(env));
- }
+ {
+ base::AutoLock locker(objects_lock_);
+ objects_[iter->second]->RemoveName();
}
+ named_objects_.erase(iter);
+
+ // As the object isn't going to be removed from the JavaScript side until the
+ // next page reload, calls to it must still work, thus we should continue to
+ // hold it. All the transient objects and removed named objects will be purged
+ // during the cleansing caused by DocumentAvailableInMainFrame event.
web_contents()->SendToAllFrames(
new GinJavaBridgeMsg_RemoveNamedObject(MSG_ROUTING_NONE, copied_name));
}
void GinJavaBridgeDispatcherHost::SetAllowObjectContentsInspection(bool allow) {
+ if (!JavaBridgeThread::CurrentlyOn()) {
+ g_background_thread.Get().message_loop()->task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &GinJavaBridgeDispatcherHost::SetAllowObjectContentsInspection,
+ this, allow));
+ return;
+ }
allow_object_contents_inspection_ = allow;
}
@@ -236,337 +288,203 @@
// Called when the window object has been cleared in the main frame.
// That means, all sub-frames have also been cleared, so only named
// objects survived.
+ AddBrowserFilterIfNeeded();
JNIEnv* env = base::android::AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> retained_object_set =
retained_object_set_.get(env);
+ base::AutoLock locker(objects_lock_);
if (!retained_object_set.is_null()) {
JNI_Java_HashSet_clear(env, retained_object_set);
}
-
- // We also need to add back the named objects we have so far as they
- // should survive navigations.
- for (GinJavaBoundObject::ObjectMap::iterator it(&objects_); !it.IsAtEnd();
- it.Advance()) {
- scoped_refptr<GinJavaBoundObject> object(*it.GetCurrentValue());
- if (object->IsNamed()) {
+ auto iter = objects_.begin();
+ while (iter != objects_.end()) {
+ if (iter->second->IsNamed()) {
if (!retained_object_set.is_null()) {
JNI_Java_HashSet_add(
- env, retained_object_set, object->GetLocalRef(env));
+ env, retained_object_set, iter->second->GetLocalRef(env));
}
+ ++iter;
} else {
- objects_.Remove(it.GetCurrentKey());
+ objects_.erase(iter++);
}
}
}
-namespace {
-
-// TODO(mnaganov): Implement passing of a parameter into sync message handlers.
-class MessageForwarder : public IPC::Sender {
- public:
- MessageForwarder(GinJavaBridgeDispatcherHost* gjbdh,
- RenderFrameHost* render_frame_host)
- : gjbdh_(gjbdh), render_frame_host_(render_frame_host) {}
- void OnGetMethods(GinJavaBoundObject::ObjectID object_id,
- IPC::Message* reply_msg) {
- gjbdh_->OnGetMethods(render_frame_host_,
- object_id,
- reply_msg);
+base::TaskRunner* GinJavaBridgeDispatcherHost::OverrideTaskRunnerForMessage(
+ const IPC::Message& message) {
+ GinJavaBoundObject::ObjectID object_id = 0;
+ // TODO(mnaganov): It's very sad that we have a BrowserMessageFilter per
+ // WebView instance. We should redesign to have a filter per RPH.
+ // Check, if the object ID in the message is known to this host. If not,
+ // this is a message for some other host. As all our IPC messages from the
+ // renderer start with object ID, we just fetch it directly from the
+ // message, considering sync and async messages separately.
+ switch (message.type()) {
+ case GinJavaBridgeHostMsg_GetMethods::ID:
+ case GinJavaBridgeHostMsg_HasMethod::ID:
+ case GinJavaBridgeHostMsg_InvokeMethod::ID: {
+ DCHECK(message.is_sync());
+ PickleIterator message_reader =
+ IPC::SyncMessage::GetDataIterator(&message);
+ if (!IPC::ReadParam(&message, &message_reader, &object_id))
+ return NULL;
+ break;
+ }
+ case GinJavaBridgeHostMsg_ObjectWrapperDeleted::ID: {
+ DCHECK(!message.is_sync());
+ PickleIterator message_reader(message);
+ if (!IPC::ReadParam(&message, &message_reader, &object_id))
+ return NULL;
+ break;
+ }
+ default:
+ NOTREACHED();
+ return NULL;
}
- void OnHasMethod(GinJavaBoundObject::ObjectID object_id,
- const std::string& method_name,
- IPC::Message* reply_msg) {
- gjbdh_->OnHasMethod(render_frame_host_,
- object_id,
- method_name,
- reply_msg);
+ {
+ base::AutoLock locker(objects_lock_);
+ if (objects_.find(object_id) != objects_.end()) {
+ return g_background_thread.Get().message_loop()->task_runner().get();
+ }
}
- void OnInvokeMethod(GinJavaBoundObject::ObjectID object_id,
- const std::string& method_name,
- const base::ListValue& arguments,
- IPC::Message* reply_msg) {
- gjbdh_->OnInvokeMethod(render_frame_host_,
- object_id,
- method_name,
- arguments,
- reply_msg);
- }
- virtual bool Send(IPC::Message* msg) override {
- NOTREACHED();
- return false;
- }
- private:
- GinJavaBridgeDispatcherHost* gjbdh_;
- RenderFrameHost* render_frame_host_;
-};
-
+ return NULL;
}
bool GinJavaBridgeDispatcherHost::OnMessageReceived(
- const IPC::Message& message,
- RenderFrameHost* render_frame_host) {
- DCHECK(render_frame_host);
+ const IPC::Message& message) {
+ // We can get here As WebContentsObserver also has OnMessageReceived,
+ // or because we have not provided a task runner in
+ // OverrideTaskRunnerForMessage. In either case, just bail out.
+ if (!JavaBridgeThread::CurrentlyOn())
+ return false;
+ SetCurrentRoutingID(message.routing_id());
bool handled = true;
- MessageForwarder forwarder(this, render_frame_host);
- IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(GinJavaBridgeDispatcherHost, message,
- render_frame_host)
- IPC_MESSAGE_FORWARD_DELAY_REPLY(GinJavaBridgeHostMsg_GetMethods,
- &forwarder,
- MessageForwarder::OnGetMethods)
- IPC_MESSAGE_FORWARD_DELAY_REPLY(GinJavaBridgeHostMsg_HasMethod,
- &forwarder,
- MessageForwarder::OnHasMethod)
- IPC_MESSAGE_FORWARD_DELAY_REPLY(GinJavaBridgeHostMsg_InvokeMethod,
- &forwarder,
- MessageForwarder::OnInvokeMethod)
+ IPC_BEGIN_MESSAGE_MAP(GinJavaBridgeDispatcherHost, message)
+ IPC_MESSAGE_HANDLER(GinJavaBridgeHostMsg_GetMethods, OnGetMethods)
+ IPC_MESSAGE_HANDLER(GinJavaBridgeHostMsg_HasMethod, OnHasMethod)
+ IPC_MESSAGE_HANDLER(GinJavaBridgeHostMsg_InvokeMethod, OnInvokeMethod)
IPC_MESSAGE_HANDLER(GinJavaBridgeHostMsg_ObjectWrapperDeleted,
OnObjectWrapperDeleted)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
+ SetCurrentRoutingID(MSG_ROUTING_NONE);
return handled;
}
-namespace {
-
-class IsValidRenderFrameHostHelper
- : public base::RefCounted<IsValidRenderFrameHostHelper> {
- public:
- explicit IsValidRenderFrameHostHelper(RenderFrameHost* rfh_to_match)
- : rfh_to_match_(rfh_to_match), rfh_found_(false) {}
-
- bool rfh_found() { return rfh_found_; }
-
- void OnFrame(RenderFrameHost* rfh) {
- if (rfh_to_match_ == rfh) rfh_found_ = true;
+void GinJavaBridgeDispatcherHost::OnDestruct() const {
+ if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ delete this;
+ } else {
+ BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, this);
}
+}
- private:
- friend class base::RefCounted<IsValidRenderFrameHostHelper>;
+int GinJavaBridgeDispatcherHost::GetCurrentRoutingID() const {
+ DCHECK(JavaBridgeThread::CurrentlyOn());
+ return current_routing_id_;
+}
- ~IsValidRenderFrameHostHelper() {}
+void GinJavaBridgeDispatcherHost::SetCurrentRoutingID(int32 routing_id) {
+ DCHECK(JavaBridgeThread::CurrentlyOn());
+ current_routing_id_ = routing_id;
+}
- RenderFrameHost* rfh_to_match_;
- bool rfh_found_;
-
- DISALLOW_COPY_AND_ASSIGN(IsValidRenderFrameHostHelper);
-};
-
-} // namespace
-
-bool GinJavaBridgeDispatcherHost::IsValidRenderFrameHost(
- RenderFrameHost* render_frame_host) {
- scoped_refptr<IsValidRenderFrameHostHelper> helper =
- new IsValidRenderFrameHostHelper(render_frame_host);
- web_contents()->ForEachFrame(
- base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper));
- return helper->rfh_found();
+scoped_refptr<GinJavaBoundObject> GinJavaBridgeDispatcherHost::FindObject(
+ GinJavaBoundObject::ObjectID object_id) {
+ // Can be called on any thread.
+ base::AutoLock locker(objects_lock_);
+ auto iter = objects_.find(object_id);
+ if (iter != objects_.end())
+ return iter->second;
+ return NULL;
}
void GinJavaBridgeDispatcherHost::OnGetMethods(
- RenderFrameHost* render_frame_host,
GinJavaBoundObject::ObjectID object_id,
- IPC::Message* reply_msg) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(render_frame_host);
- if (!allow_object_contents_inspection_) {
- IPC::WriteParam(reply_msg, std::set<std::string>());
- render_frame_host->Send(reply_msg);
+ std::set<std::string>* returned_method_names) {
+ DCHECK(JavaBridgeThread::CurrentlyOn());
+ if (!allow_object_contents_inspection_)
return;
- }
- scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
- if (!object.get()) {
+ scoped_refptr<GinJavaBoundObject> object = FindObject(object_id);
+ if (object.get()) {
+ *returned_method_names = object->GetMethodNames();
+ } else {
LOG(ERROR) << "WebView: Unknown object: " << object_id;
- IPC::WriteParam(reply_msg, std::set<std::string>());
- render_frame_host->Send(reply_msg);
- return;
}
- DCHECK(!HasPendingReply(render_frame_host));
- pending_replies_[render_frame_host] = reply_msg;
- base::PostTaskAndReplyWithResult(
- g_background_thread.Get().message_loop()->message_loop_proxy().get(),
- FROM_HERE,
- base::Bind(&GinJavaBoundObject::GetMethodNames, object),
- base::Bind(&GinJavaBridgeDispatcherHost::SendMethods,
- AsWeakPtr(),
- render_frame_host));
-}
-
-void GinJavaBridgeDispatcherHost::SendMethods(
- RenderFrameHost* render_frame_host,
- const std::set<std::string>& method_names) {
- IPC::Message* reply_msg = TakePendingReply(render_frame_host);
- if (!reply_msg) {
- return;
- }
- IPC::WriteParam(reply_msg, method_names);
- render_frame_host->Send(reply_msg);
}
void GinJavaBridgeDispatcherHost::OnHasMethod(
- RenderFrameHost* render_frame_host,
GinJavaBoundObject::ObjectID object_id,
const std::string& method_name,
- IPC::Message* reply_msg) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(render_frame_host);
- scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
- if (!object.get()) {
+ bool* result) {
+ DCHECK(JavaBridgeThread::CurrentlyOn());
+ scoped_refptr<GinJavaBoundObject> object = FindObject(object_id);
+ if (object.get()) {
+ *result = object->HasMethod(method_name);
+ } else {
LOG(ERROR) << "WebView: Unknown object: " << object_id;
- IPC::WriteParam(reply_msg, false);
- render_frame_host->Send(reply_msg);
- return;
}
- DCHECK(!HasPendingReply(render_frame_host));
- pending_replies_[render_frame_host] = reply_msg;
- base::PostTaskAndReplyWithResult(
- g_background_thread.Get().message_loop()->message_loop_proxy().get(),
- FROM_HERE,
- base::Bind(&GinJavaBoundObject::HasMethod, object, method_name),
- base::Bind(&GinJavaBridgeDispatcherHost::SendHasMethodReply,
- AsWeakPtr(),
- render_frame_host));
-}
-
-void GinJavaBridgeDispatcherHost::SendHasMethodReply(
- RenderFrameHost* render_frame_host,
- bool result) {
- IPC::Message* reply_msg = TakePendingReply(render_frame_host);
- if (!reply_msg) {
- return;
- }
- IPC::WriteParam(reply_msg, result);
- render_frame_host->Send(reply_msg);
}
void GinJavaBridgeDispatcherHost::OnInvokeMethod(
- RenderFrameHost* render_frame_host,
GinJavaBoundObject::ObjectID object_id,
const std::string& method_name,
const base::ListValue& arguments,
- IPC::Message* reply_msg) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(render_frame_host);
- scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
+ base::ListValue* wrapped_result,
+ content::GinJavaBridgeError* error_code) {
+ DCHECK(JavaBridgeThread::CurrentlyOn());
+ DCHECK(GetCurrentRoutingID() != MSG_ROUTING_NONE);
+ scoped_refptr<GinJavaBoundObject> object = FindObject(object_id);
if (!object.get()) {
LOG(ERROR) << "WebView: Unknown object: " << object_id;
- base::ListValue result;
- result.Append(base::Value::CreateNullValue());
- IPC::WriteParam(reply_msg, result);
- IPC::WriteParam(reply_msg, kGinJavaBridgeUnknownObjectId);
- render_frame_host->Send(reply_msg);
+ wrapped_result->Append(base::Value::CreateNullValue());
+ *error_code = kGinJavaBridgeUnknownObjectId;
return;
}
- DCHECK(!HasPendingReply(render_frame_host));
- pending_replies_[render_frame_host] = reply_msg;
scoped_refptr<GinJavaMethodInvocationHelper> result =
new GinJavaMethodInvocationHelper(
make_scoped_ptr(new GinJavaBoundObjectDelegate(object)),
method_name,
arguments);
result->Init(this);
- g_background_thread.Get()
- .message_loop()
- ->message_loop_proxy()
- ->PostTaskAndReply(
- FROM_HERE,
- base::Bind(&GinJavaMethodInvocationHelper::Invoke, result),
- base::Bind(
- &GinJavaBridgeDispatcherHost::ProcessMethodInvocationResult,
- AsWeakPtr(),
- render_frame_host,
- result));
-}
-
-void GinJavaBridgeDispatcherHost::ProcessMethodInvocationResult(
- RenderFrameHost* render_frame_host,
- scoped_refptr<GinJavaMethodInvocationHelper> result) {
+ result->Invoke();
+ *error_code = result->GetInvocationError();
if (result->HoldsPrimitiveResult()) {
- IPC::Message* reply_msg = TakePendingReply(render_frame_host);
- if (!reply_msg) {
- return;
- }
- IPC::WriteParam(reply_msg, result->GetPrimitiveResult());
- IPC::WriteParam(reply_msg, result->GetInvocationError());
- render_frame_host->Send(reply_msg);
- } else {
- ProcessMethodInvocationObjectResult(render_frame_host, result);
- }
-}
-
-void GinJavaBridgeDispatcherHost::ProcessMethodInvocationObjectResult(
- RenderFrameHost* render_frame_host,
- scoped_refptr<GinJavaMethodInvocationHelper> result) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- if (!IsValidRenderFrameHost(render_frame_host)) {
- // In this case, we must've already sent the reply when the render frame
- // was destroyed.
- DCHECK(!HasPendingReply(render_frame_host));
- return;
- }
-
- base::ListValue wrapped_result;
- if (!result->GetObjectResult().is_null()) {
+ scoped_ptr<base::ListValue> result_copy(
+ result->GetPrimitiveResult().DeepCopy());
+ wrapped_result->Swap(result_copy.get());
+ } else if (!result->GetObjectResult().is_null()) {
GinJavaBoundObject::ObjectID returned_object_id;
if (FindObjectId(result->GetObjectResult(), &returned_object_id)) {
- (*objects_.Lookup(returned_object_id))->AddHolder(render_frame_host);
+ base::AutoLock locker(objects_lock_);
+ objects_[returned_object_id]->AddHolder(GetCurrentRoutingID());
} else {
returned_object_id = AddObject(result->GetObjectResult(),
result->GetSafeAnnotationClass(),
false,
- render_frame_host);
+ GetCurrentRoutingID());
}
- wrapped_result.Append(
+ wrapped_result->Append(
GinJavaBridgeValue::CreateObjectIDValue(
returned_object_id).release());
} else {
- wrapped_result.Append(base::Value::CreateNullValue());
+ wrapped_result->Append(base::Value::CreateNullValue());
}
- IPC::Message* reply_msg = TakePendingReply(render_frame_host);
- if (!reply_msg) {
- return;
- }
- IPC::WriteParam(reply_msg, wrapped_result);
- IPC::WriteParam(reply_msg, result->GetInvocationError());
- render_frame_host->Send(reply_msg);
}
void GinJavaBridgeDispatcherHost::OnObjectWrapperDeleted(
- RenderFrameHost* render_frame_host,
GinJavaBoundObject::ObjectID object_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(render_frame_host);
- if (objects_.Lookup(object_id)) {
- GinJavaBoundObject::ObjectMap::iterator iter(&objects_);
- while (!iter.IsAtEnd() && iter.GetCurrentKey() != object_id)
- iter.Advance();
- DCHECK(!iter.IsAtEnd());
- RemoveHolder(render_frame_host, iter, 1);
+ DCHECK(JavaBridgeThread::CurrentlyOn());
+ DCHECK(GetCurrentRoutingID() != MSG_ROUTING_NONE);
+ base::AutoLock locker(objects_lock_);
+ auto iter = objects_.find(object_id);
+ if (iter == objects_.end())
+ return;
+ JavaObjectWeakGlobalRef ref =
+ RemoveHolderAndAdvanceLocked(GetCurrentRoutingID(), &iter);
+ if (!ref.is_empty()) {
+ RemoveFromRetainedObjectSetLocked(ref);
}
}
-IPC::Message* GinJavaBridgeDispatcherHost::TakePendingReply(
- RenderFrameHost* render_frame_host) {
- if (!IsValidRenderFrameHost(render_frame_host)) {
- DCHECK(!HasPendingReply(render_frame_host));
- return NULL;
- }
-
- PendingReplyMap::iterator it = pending_replies_.find(render_frame_host);
- // There may be no pending reply if we're called from RenderFrameDeleted and
- // we already sent the reply through the regular route.
- if (it == pending_replies_.end()) {
- return NULL;
- }
-
- IPC::Message* reply_msg = it->second;
- pending_replies_.erase(it);
- return reply_msg;
-}
-
-bool GinJavaBridgeDispatcherHost::HasPendingReply(
- RenderFrameHost* render_frame_host) const {
- return pending_replies_.find(render_frame_host) != pending_replies_.end();
-}
-
} // namespace content
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.h b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
index c57ba26..56fddee 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.h
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
@@ -12,8 +12,10 @@
#include "base/android/scoped_java_ref.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/synchronization/lock.h"
#include "content/browser/android/java/gin_java_bound_object.h"
#include "content/browser/android/java/gin_java_method_invocation_helper.h"
+#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/web_contents_observer.h"
namespace base {
@@ -31,14 +33,13 @@
// proxy object is created in the renderer. An instance of this class exists
// for each RenderFrameHost.
class GinJavaBridgeDispatcherHost
- : public base::SupportsWeakPtr<GinJavaBridgeDispatcherHost>,
- public WebContentsObserver,
+ : public WebContentsObserver,
+ public BrowserMessageFilter,
public GinJavaMethodInvocationHelper::DispatcherDelegate {
public:
GinJavaBridgeDispatcherHost(WebContents* web_contents,
jobject retained_object_set);
- virtual ~GinJavaBridgeDispatcherHost();
void AddNamedObject(
const std::string& name,
@@ -48,56 +49,68 @@
void SetAllowObjectContentsInspection(bool allow);
// WebContentsObserver
- virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) override;
- virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
- virtual void DocumentAvailableInMainFrame() override;
- virtual bool OnMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host) override;
+ void RenderFrameCreated(RenderFrameHost* render_frame_host) override;
+ void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
+ void DocumentAvailableInMainFrame() override;
+
+ // BrowserMessageFilter
+ using BrowserMessageFilter::Send;
+ void OnDestruct() const override;
+ bool OnMessageReceived(const IPC::Message& message) override;
+ base::TaskRunner* OverrideTaskRunnerForMessage(
+ const IPC::Message& message) override;
// GinJavaMethodInvocationHelper::DispatcherDelegate
- virtual JavaObjectWeakGlobalRef GetObjectWeakRef(
+ JavaObjectWeakGlobalRef GetObjectWeakRef(
GinJavaBoundObject::ObjectID object_id) override;
- void OnGetMethods(RenderFrameHost* render_frame_host,
- GinJavaBoundObject::ObjectID object_id,
- IPC::Message* reply_msg);
- void OnHasMethod(RenderFrameHost* render_frame_host,
- GinJavaBoundObject::ObjectID object_id,
- const std::string& method_name,
- IPC::Message* reply_msg);
- void OnInvokeMethod(RenderFrameHost* render_frame_host,
- GinJavaBoundObject::ObjectID object_id,
- const std::string& method_name,
- const base::ListValue& arguments,
- IPC::Message* reply_msg);
-
private:
- void OnObjectWrapperDeleted(RenderFrameHost* render_frame_host,
- GinJavaBoundObject::ObjectID object_id);
+ friend class BrowserThread;
+ friend class base::DeleteHelper<GinJavaBridgeDispatcherHost>;
- bool IsValidRenderFrameHost(RenderFrameHost* render_frame_host);
- void SendMethods(RenderFrameHost* render_frame_host,
- const std::set<std::string>& method_names);
- void SendHasMethodReply(RenderFrameHost* render_frame_host,
- bool result);
- void ProcessMethodInvocationResult(
- RenderFrameHost* render_frame_host,
- scoped_refptr<GinJavaMethodInvocationHelper> result);
- void ProcessMethodInvocationObjectResult(
- RenderFrameHost* render_frame_host,
- scoped_refptr<GinJavaMethodInvocationHelper> result);
+ typedef std::map<GinJavaBoundObject::ObjectID,
+ scoped_refptr<GinJavaBoundObject>> ObjectMap;
+
+ ~GinJavaBridgeDispatcherHost() override;
+
+ void AddBrowserFilterIfNeeded();
+
+ // Run on any thread.
GinJavaBoundObject::ObjectID AddObject(
const base::android::JavaRef<jobject>& object,
const base::android::JavaRef<jclass>& safe_annotation_clazz,
bool is_named,
- RenderFrameHost* holder);
+ int32 holder);
+ scoped_refptr<GinJavaBoundObject> FindObject(
+ GinJavaBoundObject::ObjectID object_id);
bool FindObjectId(const base::android::JavaRef<jobject>& object,
GinJavaBoundObject::ObjectID* object_id);
- void RemoveHolder(RenderFrameHost* holder,
- const GinJavaBoundObject::ObjectMap::iterator& from,
- size_t count);
- bool HasPendingReply(RenderFrameHost* render_frame_host) const;
- IPC::Message* TakePendingReply(RenderFrameHost* render_frame_host);
+ void RemoveFromRetainedObjectSetLocked(const JavaObjectWeakGlobalRef& ref);
+ JavaObjectWeakGlobalRef RemoveHolderAndAdvanceLocked(
+ int32 holder,
+ ObjectMap::iterator* iter_ptr);
+
+ // Run on the background thread.
+ void OnGetMethods(GinJavaBoundObject::ObjectID object_id,
+ std::set<std::string>* returned_method_names);
+ void OnHasMethod(GinJavaBoundObject::ObjectID object_id,
+ const std::string& method_name,
+ bool* result);
+ void OnInvokeMethod(GinJavaBoundObject::ObjectID object_id,
+ const std::string& method_name,
+ const base::ListValue& arguments,
+ base::ListValue* result,
+ content::GinJavaBridgeError* error_code);
+ void OnObjectWrapperDeleted(GinJavaBoundObject::ObjectID object_id);
+ int GetCurrentRoutingID() const;
+ void SetCurrentRoutingID(int routing_id);
+
+ bool browser_filter_added_;
+
+ typedef std::map<std::string, GinJavaBoundObject::ObjectID> NamedObjectMap;
+ NamedObjectMap named_objects_;
+
+ // The following objects are used on both threads, so locking must be used.
// Every time a GinJavaBoundObject backed by a real Java object is
// created/destroyed, we insert/remove a strong ref to that Java object into
@@ -106,17 +119,15 @@
// and defined in Java so that pushing refs into it does not create new GC
// roots that would prevent ContentViewCore from being garbage collected.
JavaObjectWeakGlobalRef retained_object_set_;
- bool allow_object_contents_inspection_;
- GinJavaBoundObject::ObjectMap objects_;
- typedef std::map<std::string, GinJavaBoundObject::ObjectID> NamedObjectMap;
- NamedObjectMap named_objects_;
+ // Note that retained_object_set_ does not need to be consistent
+ // with objects_.
+ ObjectMap objects_;
+ base::Lock objects_lock_;
- // Keep track of pending calls out to Java such that we can send a synchronous
- // reply to the renderer waiting on the response should the RenderFrame be
- // destroyed while the reply is pending.
- // Only used on the UI thread.
- typedef std::map<RenderFrameHost*, IPC::Message*> PendingReplyMap;
- PendingReplyMap pending_replies_;
+ // The following objects are only used on the background thread.
+ bool allow_object_contents_inspection_;
+ // The routing id of the RenderFrameHost whose request we are processing.
+ int32 current_routing_id_;
DISALLOW_COPY_AND_ASSIGN(GinJavaBridgeDispatcherHost);
};
diff --git a/content/browser/android/java/gin_java_method_invocation_helper.h b/content/browser/android/java/gin_java_method_invocation_helper.h
index 014e311..f7bdd57 100644
--- a/content/browser/android/java/gin_java_method_invocation_helper.h
+++ b/content/browser/android/java/gin_java_method_invocation_helper.h
@@ -20,13 +20,10 @@
class JavaMethod;
-// Instances of this class are created and initialized on the UI thread, do
-// their work on the background thread, and then again examined on the UI
-// thread. They don't work on both threads simultaneously, though.
+// Instances of this class are created and used on the background thread.
class CONTENT_EXPORT GinJavaMethodInvocationHelper
: public base::RefCountedThreadSafe<GinJavaMethodInvocationHelper> {
public:
- // DispatcherDelegate is used on the UI thread
class DispatcherDelegate {
public:
DispatcherDelegate() {}
@@ -38,7 +35,6 @@
DISALLOW_COPY_AND_ASSIGN(DispatcherDelegate);
};
- // ObjectDelegate is used in the background thread
class ObjectDelegate {
public:
ObjectDelegate() {}
@@ -61,10 +57,8 @@
const base::ListValue& arguments);
void Init(DispatcherDelegate* dispatcher);
- // Called on the background thread
void Invoke();
- // Called on the UI thread
bool HoldsPrimitiveResult();
const base::ListValue& GetPrimitiveResult();
const base::android::JavaRef<jobject>& GetObjectResult();
@@ -75,7 +69,6 @@
friend class base::RefCountedThreadSafe<GinJavaMethodInvocationHelper>;
~GinJavaMethodInvocationHelper();
- // Called on the UI thread
void BuildObjectRefsFromListValue(DispatcherDelegate* dispatcher,
const base::Value* list_value);
void BuildObjectRefsFromDictionaryValue(DispatcherDelegate* dispatcher,
@@ -84,7 +77,6 @@
bool AppendObjectRef(DispatcherDelegate* dispatcher,
const base::Value* raw_value);
- // Called on the background thread.
void InvokeMethod(jobject object,
jclass clazz,
const JavaType& return_type,
diff --git a/content/browser/compositor/delegated_frame_host.cc b/content/browser/compositor/delegated_frame_host.cc
index 5dbaed1..1e39486 100644
--- a/content/browser/compositor/delegated_frame_host.cc
+++ b/content/browser/compositor/delegated_frame_host.cc
@@ -138,7 +138,7 @@
if (resize_lock_)
return false;
- if (host->should_auto_resize())
+ if (host->auto_resize_enabled())
return false;
gfx::Size desired_size = client_->DesiredFrameSize();
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 26ecf1d..b8e3a9d 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -756,6 +756,16 @@
return handler.Pass();
}
+void ResourceDispatcherHostImpl::ClearSSLClientAuthHandlerForRequest(
+ net::URLRequest* request) {
+ ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(request);
+ if (info) {
+ ResourceLoader* loader = GetLoader(info->GetGlobalRequestID());
+ if (loader)
+ loader->ClearSSLClientAuthHandler();
+ }
+}
+
ResourceDispatcherHostLoginDelegate*
ResourceDispatcherHostImpl::CreateLoginDelegate(
ResourceLoader* loader,
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h
index a96af55..0abee9d 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -244,6 +244,8 @@
ResourceResponse* response,
std::string* payload);
+ void ClearSSLClientAuthHandlerForRequest(net::URLRequest* request);
+
ResourceScheduler* scheduler() { return scheduler_.get(); }
// Called by a ResourceHandler when it's ready to start reading data and
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc
index eae75eb..c9c24d0 100644
--- a/content/browser/loader/resource_loader.cc
+++ b/content/browser/loader/resource_loader.cc
@@ -96,7 +96,8 @@
ResourceLoader::~ResourceLoader() {
if (login_delegate_.get())
login_delegate_->OnRequestCancelled();
- ssl_client_auth_handler_.reset();
+ if (ssl_client_auth_handler_.get())
+ ssl_client_auth_handler_->OnRequestCancelled();
// Run ResourceHandler destructor before we tear-down the rest of our state
// as the ResourceHandler may want to inspect the URLRequest and other state.
@@ -196,6 +197,10 @@
login_delegate_ = NULL;
}
+void ResourceLoader::ClearSSLClientAuthHandler() {
+ ssl_client_auth_handler_ = NULL;
+}
+
void ResourceLoader::OnUploadProgressACK() {
waiting_for_upload_progress_ack_ = false;
}
@@ -268,14 +273,12 @@
return;
}
- DCHECK(!ssl_client_auth_handler_)
+ DCHECK(!ssl_client_auth_handler_.get())
<< "OnCertificateRequested called with ssl_client_auth_handler pending";
- ssl_client_auth_handler_.reset(new SSLClientAuthHandler(
+ ssl_client_auth_handler_ = new SSLClientAuthHandler(
GetRequestInfo()->GetContext()->CreateClientCertStore(),
request_.get(),
- cert_info,
- base::Bind(&ResourceLoader::ContinueWithCertificate,
- weak_ptr_factory_.GetWeakPtr())));
+ cert_info);
ssl_client_auth_handler_->SelectCertificate();
}
@@ -492,7 +495,10 @@
login_delegate_->OnRequestCancelled();
login_delegate_ = NULL;
}
- ssl_client_auth_handler_.reset();
+ if (ssl_client_auth_handler_.get()) {
+ ssl_client_auth_handler_->OnRequestCancelled();
+ ssl_client_auth_handler_ = NULL;
+ }
request_->CancelWithError(error);
@@ -708,9 +714,4 @@
}
}
-void ResourceLoader::ContinueWithCertificate(net::X509Certificate* cert) {
- ssl_client_auth_handler_.reset();
- request_->ContinueWithCertificate(cert);
-}
-
} // namespace content
diff --git a/content/browser/loader/resource_loader.h b/content/browser/loader/resource_loader.h
index d740ec0..b5c8b8a 100644
--- a/content/browser/loader/resource_loader.h
+++ b/content/browser/loader/resource_loader.h
@@ -15,10 +15,6 @@
#include "content/public/common/signed_certificate_timestamp_id_and_status.h"
#include "net/url_request/url_request.h"
-namespace net {
-class X509Certificate;
-}
-
namespace content {
class ResourceDispatcherHostLoginDelegate;
class ResourceLoaderDelegate;
@@ -50,6 +46,7 @@
ResourceRequestInfoImpl* GetRequestInfo();
void ClearLoginDelegate();
+ void ClearSSLClientAuthHandler();
// IPC message handlers:
void OnUploadProgressACK();
@@ -102,7 +99,6 @@
void ResponseCompleted();
void CallDidFinishLoading();
void RecordHistograms();
- void ContinueWithCertificate(net::X509Certificate* cert);
bool is_deferred() const { return deferred_stage_ != DEFERRED_NONE; }
@@ -133,7 +129,7 @@
ResourceLoaderDelegate* delegate_;
scoped_refptr<ResourceDispatcherHostLoginDelegate> login_delegate_;
- scoped_ptr<SSLClientAuthHandler> ssl_client_auth_handler_;
+ scoped_refptr<SSLClientAuthHandler> ssl_client_auth_handler_;
uint64 last_upload_position_;
bool waiting_for_upload_progress_ack_;
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc
index 635f566..a24305c 100644
--- a/content/browser/loader/resource_loader_unittest.cc
+++ b/content/browser/loader/resource_loader_unittest.cc
@@ -231,6 +231,7 @@
void SelectClientCertificate(
int render_process_id,
int render_view_id,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
const base::Callback<void(net::X509Certificate*)>& callback) override {
++call_count_;
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 5d8ecc8..fdca42d 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -74,11 +74,6 @@
}
virtual void SwapBuffers(cc::CompositorFrame* frame) override {
- for (size_t i = 0; i < frame->metadata.latency_info.size(); i++) {
- frame->metadata.latency_info[i].AddLatencyNumber(
- ui::INPUT_EVENT_BROWSER_SWAP_BUFFER_COMPONENT, 0, 0);
- }
-
GetCommandBufferProxy()->SetLatencyInfo(frame->metadata.latency_info);
DCHECK(frame->gl_frame_data->sub_buffer_rect ==
gfx::Rect(frame->gl_frame_data->size));
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index be30e92..c582a6e 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1126,6 +1126,7 @@
switches::kEnableGPUClientLogging,
switches::kEnableGpuClientTracing,
switches::kEnableGPUServiceLogging,
+ switches::kEnableLinkDisambiguationPopup,
switches::kEnableLowResTiling,
switches::kEnableInbandTextTracks,
switches::kEnableLCDText,
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc
index 01a5e1b..dba2fa0 100644
--- a/content/browser/renderer_host/render_view_host_impl.cc
+++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -289,9 +289,14 @@
params.never_visible = delegate_->IsNeverVisible();
params.window_was_created_with_opener = window_was_created_with_opener;
params.next_page_id = next_page_id;
- GetWebScreenInfo(¶ms.screen_info);
+ params.enable_auto_resize = auto_resize_enabled();
+ params.min_size = min_size_for_auto_resize();
+ params.max_size = max_size_for_auto_resize();
+ GetResizeParams(¶ms.initial_size);
- Send(new ViewMsg_New(params));
+ if (!Send(new ViewMsg_New(params)))
+ return false;
+ SetInitialRenderSizeParams(params.initial_size);
// If it's enabled, tell the renderer to set up the Javascript bindings for
// sending messages back to the browser.
@@ -1378,12 +1383,12 @@
void RenderViewHostImpl::EnableAutoResize(const gfx::Size& min_size,
const gfx::Size& max_size) {
- SetShouldAutoResize(true);
+ SetAutoResize(true, min_size, max_size);
Send(new ViewMsg_EnableAutoResize(GetRoutingID(), min_size, max_size));
}
void RenderViewHostImpl::DisableAutoResize(const gfx::Size& new_size) {
- SetShouldAutoResize(false);
+ SetAutoResize(false, gfx::Size(), gfx::Size());
Send(new ViewMsg_DisableAutoResize(GetRoutingID(), new_size));
if (!new_size.IsEmpty())
GetView()->SetSize(new_size);
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 9a1d709..6363c14 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -89,10 +89,6 @@
bool g_check_for_pending_resize_ack = true;
-const size_t kBrowserCompositeLatencyHistorySize = 60;
-const double kBrowserCompositeLatencyEstimationPercentile = 90.0;
-const double kBrowserCompositeLatencyEstimationSlack = 1.1;
-
typedef std::pair<int32, int32> RenderWidgetHostID;
typedef base::hash_map<RenderWidgetHostID, RenderWidgetHostImpl*>
RoutingIDWidgetMap;
@@ -167,12 +163,10 @@
surface_id_(0),
is_loading_(false),
is_hidden_(hidden),
- is_fullscreen_(false),
repaint_ack_pending_(false),
resize_ack_pending_(false),
screen_info_out_of_date_(false),
- top_controls_layout_height_(0.f),
- should_auto_resize_(false),
+ auto_resize_enabled_(false),
waiting_for_screen_rects_ack_(false),
needs_repainting_on_restore_(false),
is_unresponsive_(false),
@@ -189,7 +183,6 @@
has_touch_handler_(false),
last_input_number_(static_cast<int64>(GetProcess()->GetID()) << 32),
next_browser_snapshot_id_(1),
- browser_composite_latency_history_(kBrowserCompositeLatencyHistorySize),
weak_factory_(this) {
CHECK(delegate_);
if (routing_id_ == MSG_ROUTING_NONE) {
@@ -362,7 +355,8 @@
"renderer_host", "RenderWidgetHostImpl::repaint_ack_pending_", this);
}
repaint_ack_pending_ = false;
- last_requested_size_.SetSize(0, 0);
+ if (old_resize_params_)
+ old_resize_params_->new_size = gfx::Size();
}
void RenderWidgetHostImpl::SendScreenRects() {
@@ -564,61 +558,80 @@
WasResized();
}
-void RenderWidgetHostImpl::WasResized() {
- // Skip if the |delegate_| has already been detached because
- // it's web contents is being deleted.
- if (resize_ack_pending_ || !process_->HasConnection() || !view_ ||
- !renderer_initialized_ || should_auto_resize_ || !delegate_) {
- return;
- }
-
- gfx::Size new_size(view_->GetRequestedRendererSize());
-
- gfx::Size old_physical_backing_size = physical_backing_size_;
- physical_backing_size_ = view_->GetPhysicalBackingSize();
- bool was_fullscreen = is_fullscreen_;
- is_fullscreen_ = IsFullscreen();
- float old_top_controls_layout_height =
- top_controls_layout_height_;
- top_controls_layout_height_ =
- view_->GetTopControlsLayoutHeight();
- gfx::Size old_visible_viewport_size = visible_viewport_size_;
- visible_viewport_size_ = view_->GetVisibleViewportSize();
-
- bool size_changed = new_size != last_requested_size_;
- bool side_payload_changed =
- screen_info_out_of_date_ ||
- old_physical_backing_size != physical_backing_size_ ||
- was_fullscreen != is_fullscreen_ ||
- old_top_controls_layout_height !=
- top_controls_layout_height_ ||
- old_visible_viewport_size != visible_viewport_size_;
-
- if (!size_changed && !side_payload_changed)
- return;
+void RenderWidgetHostImpl::GetResizeParams(
+ ViewMsg_Resize_Params* resize_params) {
+ *resize_params = ViewMsg_Resize_Params();
if (!screen_info_) {
screen_info_.reset(new blink::WebScreenInfo);
GetWebScreenInfo(screen_info_.get());
}
+ resize_params->screen_info = *screen_info_;
+ resize_params->resizer_rect = GetRootWindowResizerRect();
+
+ if (view_) {
+ resize_params->new_size = view_->GetRequestedRendererSize();
+ resize_params->physical_backing_size = view_->GetPhysicalBackingSize();
+ resize_params->top_controls_layout_height =
+ view_->GetTopControlsLayoutHeight();
+ resize_params->visible_viewport_size = view_->GetVisibleViewportSize();
+ resize_params->is_fullscreen = IsFullscreen();
+ }
+}
+
+void RenderWidgetHostImpl::SetInitialRenderSizeParams(
+ const ViewMsg_Resize_Params& resize_params) {
+ // We don't expect to receive an ACK when the requested size or the physical
+ // backing size is empty, or when the main viewport size didn't change.
+ if (!resize_params.new_size.IsEmpty() &&
+ !resize_params.physical_backing_size.IsEmpty()) {
+ resize_ack_pending_ = g_check_for_pending_resize_ack;
+ }
+
+ old_resize_params_ =
+ make_scoped_ptr(new ViewMsg_Resize_Params(resize_params));
+}
+
+void RenderWidgetHostImpl::WasResized() {
+ // Skip if the |delegate_| has already been detached because
+ // it's web contents is being deleted.
+ if (resize_ack_pending_ || !process_->HasConnection() || !view_ ||
+ !renderer_initialized_ || auto_resize_enabled_ || !delegate_) {
+ return;
+ }
+
+ bool size_changed = true;
+ bool side_payload_changed = screen_info_out_of_date_;
+ scoped_ptr<ViewMsg_Resize_Params> params(new ViewMsg_Resize_Params);
+
+ GetResizeParams(params.get());
+ if (old_resize_params_) {
+ size_changed = old_resize_params_->new_size != params->new_size;
+ side_payload_changed =
+ side_payload_changed ||
+ old_resize_params_->physical_backing_size !=
+ params->physical_backing_size ||
+ old_resize_params_->is_fullscreen != params->is_fullscreen ||
+ old_resize_params_->top_controls_layout_height !=
+ params->top_controls_layout_height ||
+ old_resize_params_->visible_viewport_size !=
+ params->visible_viewport_size;
+ }
+
+ if (!size_changed && !side_payload_changed)
+ return;
// We don't expect to receive an ACK when the requested size or the physical
// backing size is empty, or when the main viewport size didn't change.
- if (!new_size.IsEmpty() && !physical_backing_size_.IsEmpty() && size_changed)
+ if (!params->new_size.IsEmpty() && !params->physical_backing_size.IsEmpty() &&
+ size_changed) {
resize_ack_pending_ = g_check_for_pending_resize_ack;
+ }
- ViewMsg_Resize_Params params;
- params.screen_info = *screen_info_;
- params.new_size = new_size;
- params.physical_backing_size = physical_backing_size_;
- params.top_controls_layout_height = top_controls_layout_height_;
- params.visible_viewport_size = visible_viewport_size_;
- params.resizer_rect = GetRootWindowResizerRect();
- params.is_fullscreen = is_fullscreen_;
- if (!Send(new ViewMsg_Resize(routing_id_, params))) {
+ if (!Send(new ViewMsg_Resize(routing_id_, *params))) {
resize_ack_pending_ = false;
} else {
- last_requested_size_ = new_size;
+ old_resize_params_.swap(params);
}
}
@@ -746,7 +759,7 @@
// size of the view_. (For auto-sized views, current_size_ is updated during
// UpdateRect messages.)
gfx::Size view_size = current_size_;
- if (!should_auto_resize_) {
+ if (!auto_resize_enabled_) {
// Get the desired size from the current view bounds.
gfx::Rect view_rect = view_->GetViewBounds();
if (view_rect.IsEmpty())
@@ -800,7 +813,7 @@
// For auto-resized views, current_size_ determines the view_size and it
// may have changed during the handling of an UpdateRect message.
- if (should_auto_resize_)
+ if (auto_resize_enabled_)
view_size = current_size_;
// Break now if we got a backing store or accelerated surface of the
@@ -1380,8 +1393,12 @@
return false;
}
-void RenderWidgetHostImpl::SetShouldAutoResize(bool enable) {
- should_auto_resize_ = enable;
+void RenderWidgetHostImpl::SetAutoResize(bool enable,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size) {
+ auto_resize_enabled_ = enable;
+ min_size_for_auto_resize_ = min_size;
+ max_size_for_auto_resize_ = max_size;
}
void RenderWidgetHostImpl::Destroy() {
@@ -1505,11 +1522,6 @@
input_router_->OnViewUpdated(
GetInputRouterViewFlagsFromCompositorFrameMetadata(frame->metadata));
- for (size_t i = 0; i < frame->metadata.latency_info.size(); ++i) {
- frame->metadata.latency_info[i].AddLatencyNumber(
- ui::INPUT_EVENT_BROWSER_COMPOSITE_COMPONENT, 0, 0);
- }
-
if (view_) {
view_->OnSwapCompositorFrame(output_surface_id, frame.Pass());
view_->DidReceiveRendererFrame();
@@ -1581,7 +1593,7 @@
DidUpdateBackingStore(params, paint_start);
- if (should_auto_resize_) {
+ if (auto_resize_enabled_) {
bool post_callback = new_auto_size_.IsEmpty();
new_auto_size_ = params.view_size;
if (post_callback) {
@@ -2073,7 +2085,7 @@
// indicate that no callback is in progress (i.e. without this line
// DelayedAutoResized will not get called again).
new_auto_size_.SetSize(0, 0);
- if (!should_auto_resize_)
+ if (!auto_resize_enabled_)
return;
OnRenderAutoResized(new_size);
@@ -2215,21 +2227,6 @@
100);
}
}
-
- ui::LatencyInfo::LatencyComponent gpu_swap_component;
- if (!latency_info.FindLatency(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, &gpu_swap_component)) {
- return;
- }
-
- ui::LatencyInfo::LatencyComponent composite_component;
- if (latency_info.FindLatency(ui::INPUT_EVENT_BROWSER_COMPOSITE_COMPONENT,
- 0,
- &composite_component)) {
- base::TimeDelta delta =
- gpu_swap_component.event_time - composite_component.event_time;
- browser_composite_latency_history_.InsertSample(delta);
- }
}
void RenderWidgetHostImpl::DidReceiveRendererFrame() {
@@ -2403,17 +2400,6 @@
delegate_->GetOrCreateRootBrowserAccessibilityManager() : NULL;
}
-base::TimeDelta RenderWidgetHostImpl::GetEstimatedBrowserCompositeTime() {
- // TODO(orglofch) remove lower bound on estimate once we're sure it won't
- // cause regressions
- return std::max(
- browser_composite_latency_history_.Percentile(
- kBrowserCompositeLatencyEstimationPercentile) *
- kBrowserCompositeLatencyEstimationSlack,
- base::TimeDelta::FromMicroseconds(
- (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60)));
-}
-
#if defined(OS_WIN)
gfx::NativeViewAccessible
RenderWidgetHostImpl::GetParentNativeViewAccessible() {
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 71aa04f..2c28134 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -23,7 +23,6 @@
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
-#include "cc/base/rolling_time_delta_history.h"
#include "cc/resources/shared_bitmap.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/input/input_ack_handler.h"
@@ -46,6 +45,7 @@
struct ViewHostMsg_SelectionBounds_Params;
struct ViewHostMsg_TextInputState_Params;
struct ViewHostMsg_UpdateRect_Params;
+struct ViewMsg_Resize_Params;
namespace base {
class TimeTicks;
@@ -435,7 +435,17 @@
// Indicates whether the renderer drives the RenderWidgetHosts's size or the
// other way around.
- bool should_auto_resize() { return should_auto_resize_; }
+ bool auto_resize_enabled() { return auto_resize_enabled_; }
+
+ // The minimum size of this renderer when auto-resize is enabled.
+ const gfx::Size& min_size_for_auto_resize() const {
+ return min_size_for_auto_resize_;
+ }
+
+ // The maximum size of this renderer when auto-resize is enabled.
+ const gfx::Size& max_size_for_auto_resize() const {
+ return max_size_for_auto_resize_;
+ }
void FrameSwapped(const ui::LatencyInfo& latency_info);
void DidReceiveRendererFrame();
@@ -470,8 +480,6 @@
// or create it if it doesn't already exist.
BrowserAccessibilityManager* GetOrCreateRootBrowserAccessibilityManager();
- base::TimeDelta GetEstimatedBrowserCompositeTime();
-
#if defined(OS_WIN)
gfx::NativeViewAccessible GetParentNativeViewAccessible();
#endif
@@ -543,7 +551,16 @@
// Indicates if the render widget host should track the render widget's size
// as opposed to visa versa.
- void SetShouldAutoResize(bool enable);
+ void SetAutoResize(bool enable,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size);
+
+ // Fills in the |resize_params| struct.
+ void GetResizeParams(ViewMsg_Resize_Params* resize_params);
+
+ // Sets the |resize_params| that were sent to the renderer bundled with the
+ // request to create a new RenderWidget.
+ void SetInitialRenderSizeParams(const ViewMsg_Resize_Params& resize_params);
// Expose increment/decrement of the in-flight event count, so
// RenderViewHostImpl can account for in-flight beforeunload/unload events.
@@ -702,9 +719,6 @@
// most recent call to process_->WidgetRestored() / WidgetHidden().
bool is_hidden_;
- // Indicates whether a page is fullscreen or not.
- bool is_fullscreen_;
-
// Set if we are waiting for a repaint ack for the view.
bool repaint_ack_pending_;
@@ -722,31 +736,21 @@
// The current size of the RenderWidget.
gfx::Size current_size_;
- // The size of the view's backing surface in non-DPI-adjusted pixels.
- gfx::Size physical_backing_size_;
-
- // The amount that the viewport size given to Blink was shrunk by the URL-bar
- // (always 0 on platforms where URL-bar hiding isn't supported).
- float top_controls_layout_height_;
-
- // The size of the visible viewport, which may be smaller than the view if the
- // view is partially occluded (e.g. by a virtual keyboard). The size is in
- // DPI-adjusted pixels.
- gfx::Size visible_viewport_size_;
-
- // The size we last sent as requested size to the renderer. |current_size_|
- // is only updated once the resize message has been ack'd. This on the other
- // hand is updated when the resize message is sent. This is very similar to
- // |resize_ack_pending_|, but the latter is not set if the new size has width
- // or height zero, which is why we need this too.
- gfx::Size last_requested_size_;
+ // Resize information that was previously sent to the renderer.
+ scoped_ptr<ViewMsg_Resize_Params> old_resize_params_;
// The next auto resize to send.
gfx::Size new_auto_size_;
// True if the render widget host should track the render widget's size as
// opposed to visa versa.
- bool should_auto_resize_;
+ bool auto_resize_enabled_;
+
+ // The minimum size for the render widget if auto-resize is enabled.
+ gfx::Size min_size_for_auto_resize_;
+
+ // The maximum size for the render widget if auto-resize is enabled.
+ gfx::Size max_size_for_auto_resize_;
bool waiting_for_screen_rects_ack_;
gfx::Rect last_view_screen_rect_;
@@ -843,8 +847,6 @@
base::Callback<void(const unsigned char*, size_t)> > PendingSnapshotMap;
PendingSnapshotMap pending_browser_snapshots_;
- cc::RollingTimeDeltaHistory browser_composite_latency_history_;
-
base::WeakPtrFactory<RenderWidgetHostImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 830ab01..32ed9c8 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -139,9 +139,11 @@
}
// Allow poking at a few private members.
+ using RenderWidgetHostImpl::GetResizeParams;
using RenderWidgetHostImpl::OnUpdateRect;
using RenderWidgetHostImpl::RendererExited;
- using RenderWidgetHostImpl::last_requested_size_;
+ using RenderWidgetHostImpl::SetInitialRenderSizeParams;
+ using RenderWidgetHostImpl::old_resize_params_;
using RenderWidgetHostImpl::is_hidden_;
using RenderWidgetHostImpl::resize_ack_pending_;
using RenderWidgetHostImpl::input_router_;
@@ -440,10 +442,13 @@
host_.reset(
new MockRenderWidgetHost(delegate_.get(), process_, MSG_ROUTING_NONE));
view_.reset(new TestView(host_.get()));
+ ConfigureView(view_.get());
host_->SetView(view_.get());
+ SetInitialRenderSizeParams();
host_->Init();
host_->DisableGestureDebounce();
}
+
void TearDown() override {
view_.reset();
host_.reset();
@@ -464,6 +469,15 @@
base::MessageLoop::current()->RunUntilIdle();
}
+ void SetInitialRenderSizeParams() {
+ ViewMsg_Resize_Params render_size_params;
+ host_->GetResizeParams(&render_size_params);
+ host_->SetInitialRenderSizeParams(render_size_params);
+ }
+
+ virtual void ConfigureView(TestView* view) {
+ }
+
int64 GetLatencyComponentId() {
return host_->GetLatencyComponentId();
}
@@ -630,7 +644,7 @@
view_->SetMockPhysicalBackingSize(gfx::Size());
host_->WasResized();
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(original_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Setting the bounds to a "real" rect should send out the notification.
@@ -639,7 +653,7 @@
view_->ClearMockPhysicalBackingSize();
host_->WasResized();
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(original_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Send out a update that's not a resize ack after setting resize ack pending
@@ -654,7 +668,7 @@
process_->InitUpdateRectParams(¶ms);
host_->OnUpdateRect(params);
EXPECT_TRUE(host_->resize_ack_pending_);
- EXPECT_EQ(second_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
// Sending out a new notification should NOT send out a new IPC message since
// a resize ACK is pending.
@@ -663,7 +677,7 @@
view_->set_bounds(third_size);
host_->WasResized();
EXPECT_TRUE(host_->resize_ack_pending_);
- EXPECT_EQ(second_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(second_size.size(), host_->old_resize_params_->new_size);
EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Send a update that's a resize ack, but for the original_size we sent. Since
@@ -674,7 +688,7 @@
params.view_size = original_size.size();
host_->OnUpdateRect(params);
EXPECT_TRUE(host_->resize_ack_pending_);
- EXPECT_EQ(third_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
ASSERT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Send the resize ack for the latest size.
@@ -682,7 +696,7 @@
params.view_size = third_size.size();
host_->OnUpdateRect(params);
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(third_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(third_size.size(), host_->old_resize_params_->new_size);
ASSERT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
// Now clearing the bounds should send out a notification but we shouldn't
@@ -692,7 +706,7 @@
view_->set_bounds(gfx::Rect());
host_->WasResized();
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
+ EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Send a rect that has no area but has either width or height set.
@@ -700,21 +714,21 @@
view_->set_bounds(gfx::Rect(0, 0, 0, 30));
host_->WasResized();
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
+ EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Set the same size again. It should not be sent again.
process_->sink().ClearMessages();
host_->WasResized();
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(gfx::Size(0, 30), host_->last_requested_size_);
+ EXPECT_EQ(gfx::Size(0, 30), host_->old_resize_params_->new_size);
EXPECT_FALSE(process_->sink().GetFirstMessageMatching(ViewMsg_Resize::ID));
// A different size should be sent again, however.
view_->set_bounds(gfx::Rect(0, 0, 0, 31));
host_->WasResized();
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(gfx::Size(0, 31), host_->last_requested_size_);
+ EXPECT_EQ(gfx::Size(0, 31), host_->old_resize_params_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
}
@@ -729,7 +743,7 @@
view_->set_bounds(original_size);
host_->WasResized();
EXPECT_TRUE(host_->resize_ack_pending_);
- EXPECT_EQ(original_size.size(), host_->last_requested_size_);
+ EXPECT_EQ(original_size.size(), host_->old_resize_params_->new_size);
EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
// Simulate a renderer crash before the update message. Ensure all the
@@ -738,7 +752,7 @@
host_->SetView(NULL);
host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
EXPECT_FALSE(host_->resize_ack_pending_);
- EXPECT_EQ(gfx::Size(), host_->last_requested_size_);
+ EXPECT_EQ(gfx::Size(), host_->old_resize_params_->new_size);
// Reset the view so we can exit the test cleanly.
host_->SetView(view_.get());
@@ -1494,4 +1508,39 @@
ASSERT_FALSE(host_->input_router()->HasPendingEvents());
}
+TEST_F(RenderWidgetHostTest, ResizeParams) {
+ gfx::Rect bounds(0, 0, 100, 100);
+ gfx::Size physical_backing_size(40, 50);
+ view_->set_bounds(bounds);
+ view_->SetMockPhysicalBackingSize(physical_backing_size);
+
+ ViewMsg_Resize_Params resize_params;
+ host_->GetResizeParams(&resize_params);
+ EXPECT_EQ(bounds.size(), resize_params.new_size);
+ EXPECT_EQ(physical_backing_size, resize_params.physical_backing_size);
+}
+
+class RenderWidgetHostInitialSizeTest : public RenderWidgetHostTest {
+ public:
+ RenderWidgetHostInitialSizeTest()
+ : RenderWidgetHostTest(), initial_size_(200, 100) {}
+
+ virtual void ConfigureView(TestView* view) override {
+ view->set_bounds(gfx::Rect(initial_size_));
+ }
+
+ protected:
+ gfx::Size initial_size_;
+};
+
+TEST_F(RenderWidgetHostInitialSizeTest, InitialSize) {
+ // Having an initial size set means that the size information had been sent
+ // with the reqiest to new up the RenderView and so subsequent WasResized
+ // calls should not result in new IPC (unless the size has actually changed).
+ host_->WasResized();
+ EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
+ EXPECT_EQ(initial_size_, host_->old_resize_params_->new_size);
+ EXPECT_TRUE(host_->resize_ack_pending_);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index e8a4f55..8c5b214 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -279,9 +279,7 @@
gesture_provider_(CreateGestureProviderConfig(), this),
gesture_text_selector_(this),
accelerated_surface_route_id_(0),
- using_synchronous_compositor_(SynchronousCompositorImpl::FromID(
- widget_host->GetProcess()->GetID(),
- widget_host->GetRoutingID()) != NULL),
+ using_browser_compositor_(CompositorImpl::IsInitialized()),
frame_evictor_(new DelegatedFrameEvictor(this)),
locks_on_frame_count_(0),
observing_root_window_(false),
@@ -670,7 +668,7 @@
}
void RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame(bool enabled) {
- DCHECK(!using_synchronous_compositor_);
+ DCHECK(using_browser_compositor_);
TRACE_EVENT1("cc", "RenderWidgetHostViewAndroid::OnSetNeedsBeginFrame",
"enabled", enabled);
if (enabled)
@@ -841,7 +839,7 @@
return;
}
base::TimeTicks start_time = base::TimeTicks::Now();
- if (!using_synchronous_compositor_ && !IsSurfaceAvailableForCopy()) {
+ if (using_browser_compositor_ && !IsSurfaceAvailableForCopy()) {
callback.Run(false, SkBitmap());
return;
}
@@ -853,7 +851,7 @@
gfx::Rect src_subrect_in_pixel =
ConvertRectToPixel(device_scale_factor, src_subrect);
- if (using_synchronous_compositor_) {
+ if (!using_browser_compositor_) {
SynchronousCopyContents(src_subrect_in_pixel, dst_size_in_pixel, callback,
color_type);
UMA_HISTOGRAM_TIMES("Compositing.CopyFromSurfaceTimeSynchronous",
@@ -1143,12 +1141,12 @@
bool RenderWidgetHostViewAndroid::SupportsAnimation() const {
// The synchronous (WebView) compositor does not have a proper browser
// compositor with which to drive animations.
- return !using_synchronous_compositor_;
+ return using_browser_compositor_;
}
void RenderWidgetHostViewAndroid::SetNeedsAnimate() {
DCHECK(content_view_core_);
- DCHECK(!using_synchronous_compositor_);
+ DCHECK(using_browser_compositor_);
content_view_core_->GetWindowAndroid()->SetNeedsAnimate();
}
@@ -1178,7 +1176,7 @@
scoped_ptr<TouchHandleDrawable> RenderWidgetHostViewAndroid::CreateDrawable() {
DCHECK(content_view_core_);
- if (using_synchronous_compositor_)
+ if (!using_browser_compositor_)
return content_view_core_->CreatePopupTouchHandleDrawable();
return scoped_ptr<TouchHandleDrawable>(new CompositedTouchHandleDrawable(
@@ -1285,7 +1283,7 @@
void RenderWidgetHostViewAndroid::RequestVSyncUpdate(uint32 requests) {
// The synchronous compositor does not requre BeginFrame messages.
- if (using_synchronous_compositor_)
+ if (!using_browser_compositor_)
requests &= FLUSH_INPUT;
bool should_request_vsync = !outstanding_vsync_requests_ && requests;
@@ -1330,8 +1328,12 @@
"frame_time_us", frame_time.ToInternalValue());
base::TimeTicks display_time = frame_time + vsync_period;
- base::TimeTicks deadline =
- display_time - host_->GetEstimatedBrowserCompositeTime();
+ // TODO(brianderson): Use adaptive draw-time estimation.
+ base::TimeDelta estimated_browser_composite_time =
+ base::TimeDelta::FromMicroseconds(
+ (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60));
+
+ base::TimeTicks deadline = display_time - estimated_browser_composite_time;
host_->Send(new ViewMsg_BeginFrame(
host_->GetRoutingID(),
@@ -1375,7 +1377,7 @@
gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
gfx::GLSurfaceHandle handle =
gfx::GLSurfaceHandle(gfx::kNullPluginWindow, gfx::NULL_TRANSPORT);
- if (CompositorImpl::IsInitialized()) {
+ if (using_browser_compositor_) {
handle.parent_client_id =
ImageTransportFactoryAndroid::GetInstance()->GetChannelID();
}
@@ -1645,7 +1647,7 @@
void RenderWidgetHostViewAndroid::OnDetachCompositor() {
DCHECK(content_view_core_);
- DCHECK(!using_synchronous_compositor_);
+ DCHECK(using_browser_compositor_);
RunAckCallbacks();
overscroll_effect_.reset();
}
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index 129b773..97b2ba4 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -396,7 +396,7 @@
// Size to use if we have no backing ContentViewCore
gfx::Size default_size_;
- const bool using_synchronous_compositor_;
+ const bool using_browser_compositor_;
scoped_ptr<DelegatedFrameEvictor> frame_evictor_;
diff --git a/content/browser/ssl/ssl_client_auth_handler.cc b/content/browser/ssl/ssl_client_auth_handler.cc
index 8cab2c7..72231f4 100644
--- a/content/browser/ssl/ssl_client_auth_handler.cc
+++ b/content/browser/ssl/ssl_client_auth_handler.cc
@@ -5,84 +5,77 @@
#include "content/browser/ssl/ssl_client_auth_handler.h"
#include "base/bind.h"
-#include "base/logging.h"
+#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "net/cert/x509_certificate.h"
+#include "net/http/http_transaction_factory.h"
#include "net/ssl/client_cert_store.h"
#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
namespace content {
-namespace {
-
-typedef base::Callback<void(net::X509Certificate*)> CertificateCallback;
-
-void CertificateSelectedOnUIThread(
- const CertificateCallback& io_thread_callback,
- net::X509Certificate* cert) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(io_thread_callback, make_scoped_refptr(cert)));
-}
-
-void SelectCertificateOnUIThread(
- int render_process_host_id,
- int render_frame_host_id,
- net::SSLCertRequestInfo* cert_request_info,
- const CertificateCallback& io_thread_callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- GetContentClient()->browser()->SelectClientCertificate(
- render_process_host_id, render_frame_host_id, cert_request_info,
- base::Bind(&CertificateSelectedOnUIThread, io_thread_callback));
-}
-
-} // namespace
-
SSLClientAuthHandler::SSLClientAuthHandler(
scoped_ptr<net::ClientCertStore> client_cert_store,
net::URLRequest* request,
- net::SSLCertRequestInfo* cert_request_info,
- const SSLClientAuthHandler::CertificateCallback& callback)
+ net::SSLCertRequestInfo* cert_request_info)
: request_(request),
+ http_network_session_(
+ request_->context()->http_transaction_factory()->GetSession()),
cert_request_info_(cert_request_info),
- client_cert_store_(client_cert_store.Pass()),
- callback_(callback),
- weak_factory_(this) {
+ client_cert_store_(client_cert_store.Pass()) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
}
SSLClientAuthHandler::~SSLClientAuthHandler() {
+ // If we were simply dropped, then act as if we selected no certificate.
+ DoCertificateSelected(NULL);
+}
+
+void SSLClientAuthHandler::OnRequestCancelled() {
+ request_ = NULL;
}
void SSLClientAuthHandler::SelectCertificate() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(request_);
if (client_cert_store_) {
client_cert_store_->GetClientCerts(
*cert_request_info_,
&cert_request_info_->client_certs,
- base::Bind(&SSLClientAuthHandler::DidGetClientCerts,
- weak_factory_.GetWeakPtr()));
+ base::Bind(&SSLClientAuthHandler::DidGetClientCerts, this));
} else {
DidGetClientCerts();
}
}
+void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ DVLOG(1) << this << " CertificateSelected " << cert;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(
+ &SSLClientAuthHandler::DoCertificateSelected, this,
+ make_scoped_refptr(cert)));
+}
+
void SSLClientAuthHandler::DidGetClientCerts() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Request may have cancelled while we were getting client certs.
+ if (!request_)
+ return;
// Note that if |client_cert_store_| is NULL, we intentionally fall through to
// DoCertificateSelected. This is for platforms where the client cert matching
- // is not performed by Chrome. Those platforms handle the cert matching before
- // showing the dialog.
+ // is not performed by Chrome, the platform can handle the cert matching
+ // before showing the dialog.
if (client_cert_store_ && cert_request_info_->client_certs.empty()) {
// No need to query the user if there are no certs to choose from.
- CertificateSelected(NULL);
+ DoCertificateSelected(NULL);
return;
}
@@ -90,27 +83,43 @@
int render_frame_host_id;
if (!ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame(
&render_process_host_id,
- &render_frame_host_id)) {
+ &render_frame_host_id))
NOTREACHED();
- CertificateSelected(NULL);
- return;
- }
+ // If the RVH does not exist by the time this task gets run, then the task
+ // will be dropped and the scoped_refptr to SSLClientAuthHandler will go
+ // away, so we do not leak anything. The destructor takes care of ensuring
+ // the net::URLRequest always gets a response.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&SelectCertificateOnUIThread,
- render_process_host_id, render_frame_host_id,
- cert_request_info_,
- base::Bind(&SSLClientAuthHandler::CertificateSelected,
- weak_factory_.GetWeakPtr())));
+ base::Bind(
+ &SSLClientAuthHandler::DoSelectCertificate, this,
+ render_process_host_id, render_frame_host_id));
}
-void SSLClientAuthHandler::CertificateSelected(net::X509Certificate* cert) {
+void SSLClientAuthHandler::DoCertificateSelected(net::X509Certificate* cert) {
VLOG(1) << this << " DoCertificateSelected " << cert;
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // request_ could have been NULLed if the request was cancelled while the
+ // user was choosing a cert, or because we have already responded to the
+ // certificate.
+ if (request_) {
+ request_->ContinueWithCertificate(cert);
- callback_.Run(cert);
- // |this| may be deleted at this point.
+ ResourceDispatcherHostImpl::Get()->
+ ClearSSLClientAuthHandlerForRequest(request_);
+ request_ = NULL;
+ }
+}
+
+void SSLClientAuthHandler::DoSelectCertificate(
+ int render_process_host_id, int render_frame_host_id) {
+ GetContentClient()->browser()->SelectClientCertificate(
+ render_process_host_id,
+ render_frame_host_id,
+ http_network_session_,
+ cert_request_info_.get(),
+ base::Bind(&SSLClientAuthHandler::CertificateSelected, this));
}
} // namespace content
diff --git a/content/browser/ssl/ssl_client_auth_handler.h b/content/browser/ssl/ssl_client_auth_handler.h
index f95e65d..b848d54 100644
--- a/content/browser/ssl/ssl_client_auth_handler.h
+++ b/content/browser/ssl/ssl_client_auth_handler.h
@@ -6,57 +6,79 @@
#define CONTENT_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_
#include "base/basictypes.h"
-#include "base/callback.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
+#include "base/sequenced_task_runner_helpers.h"
+#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "net/ssl/ssl_cert_request_info.h"
namespace net {
class ClientCertStore;
+class HttpNetworkSession;
class URLRequest;
class X509Certificate;
} // namespace net
namespace content {
-// This class handles the approval and selection of a certificate for SSL client
-// authentication by the user. Should only be used on the IO thread. If the
-// SSLClientAuthHandler is destroyed before the certificate is selected, the
-// selection is canceled and the callback never called.
-class SSLClientAuthHandler {
- public:
- typedef base::Callback<void(net::X509Certificate*)> CertificateCallback;
+class ResourceContext;
+// This class handles the approval and selection of a certificate for SSL client
+// authentication by the user.
+// It is self-owned and deletes itself when the UI reports the user selection or
+// when the net::URLRequest is cancelled.
+class CONTENT_EXPORT SSLClientAuthHandler
+ : public base::RefCountedThreadSafe<
+ SSLClientAuthHandler, BrowserThread::DeleteOnIOThread> {
+ public:
SSLClientAuthHandler(scoped_ptr<net::ClientCertStore> client_cert_store,
net::URLRequest* request,
- net::SSLCertRequestInfo* cert_request_info,
- const CertificateCallback& callback);
- ~SSLClientAuthHandler();
+ net::SSLCertRequestInfo* cert_request_info);
// Selects a certificate and resumes the URL request with that certificate.
+ // Should only be called on the IO thread.
void SelectCertificate();
+ // Invoked when the request associated with this handler is cancelled.
+ // Should only be called on the IO thread.
+ void OnRequestCancelled();
+
+ // Calls DoCertificateSelected on the I/O thread.
+ // Called on the UI thread after the user has made a selection (which may
+ // be long after DoSelectCertificate returns, if the UI is modeless/async.)
+ void CertificateSelected(net::X509Certificate* cert);
+
+ protected:
+ virtual ~SSLClientAuthHandler();
+
private:
+ friend class base::RefCountedThreadSafe<
+ SSLClientAuthHandler, BrowserThread::DeleteOnIOThread>;
+ friend class BrowserThread;
+ friend class base::DeleteHelper<SSLClientAuthHandler>;
+
// Called when ClientCertStore is done retrieving the cert list.
void DidGetClientCerts();
- // Called when the user has selected a cert.
- void CertificateSelected(net::X509Certificate* cert);
+ // Notifies that the user has selected a cert.
+ // Called on the IO thread.
+ void DoCertificateSelected(net::X509Certificate* cert);
+
+ // Selects a client certificate on the UI thread.
+ void DoSelectCertificate(int render_process_host_id,
+ int render_frame_host_id);
// The net::URLRequest that triggered this client auth.
net::URLRequest* request_;
+ // The HttpNetworkSession |request_| is associated with.
+ const net::HttpNetworkSession* http_network_session_;
+
// The certs to choose from.
scoped_refptr<net::SSLCertRequestInfo> cert_request_info_;
scoped_ptr<net::ClientCertStore> client_cert_store_;
- // The callback to call when the certificate is selected.
- CertificateCallback callback_;
-
- base::WeakPtrFactory<SSLClientAuthHandler> weak_factory_;
-
DISALLOW_COPY_AND_ASSIGN(SSLClientAuthHandler);
};
diff --git a/content/common/gpu/image_transport_surface.cc b/content/common/gpu/image_transport_surface.cc
index c084772..4ca2157 100644
--- a/content/common/gpu/image_transport_surface.cc
+++ b/content/common/gpu/image_transport_surface.cc
@@ -223,10 +223,6 @@
// GetVsyncValues before SwapBuffers to work around Mali driver bug:
// crbug.com/223558.
SendVSyncUpdateIfAvailable();
- for (size_t i = 0; i < latency_info_.size(); ++i) {
- latency_info_[i].AddLatencyNumber(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0);
- }
bool result = gfx::GLSurfaceAdapter::SwapBuffers();
for (size_t i = 0; i < latency_info_.size(); i++) {
latency_info_[i].AddLatencyNumber(
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 2f71b82..df8ec5b 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -377,12 +377,12 @@
texture_manager->SetLevelInfo(texture_ref,
texture_target_,
0,
- 0,
+ GL_RGBA,
texture_dimensions_.width(),
texture_dimensions_.height(),
1,
0,
- 0,
+ GL_RGBA,
0,
false);
} else {
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 426ac1f..bb55e85 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -413,6 +413,26 @@
IPC_STRUCT_MEMBER(int, flags)
IPC_STRUCT_END()
+IPC_STRUCT_BEGIN(ViewMsg_Resize_Params)
+ // Information about the screen (dpi, depth, etc..).
+ IPC_STRUCT_MEMBER(blink::WebScreenInfo, screen_info)
+ // The size of the renderer.
+ IPC_STRUCT_MEMBER(gfx::Size, new_size)
+ // The size of the view's backing surface in non-DPI-adjusted pixels.
+ IPC_STRUCT_MEMBER(gfx::Size, physical_backing_size)
+ // The amount that the viewport size given to Blink was shrunk by the URL-bar
+ // (always 0 on platforms where URL-bar hiding isn't supported).
+ IPC_STRUCT_MEMBER(float, top_controls_layout_height)
+ // The size of the visible viewport, which may be smaller than the view if the
+ // view is partially occluded (e.g. by a virtual keyboard). The size is in
+ // DPI-adjusted pixels.
+ IPC_STRUCT_MEMBER(gfx::Size, visible_viewport_size)
+ // The resizer rect.
+ IPC_STRUCT_MEMBER(gfx::Rect, resizer_rect)
+ // Indicates whether a page is fullscreen or not.
+ IPC_STRUCT_MEMBER(bool, is_fullscreen)
+IPC_STRUCT_END()
+
IPC_STRUCT_BEGIN(ViewMsg_New_Params)
// Renderer-wide preferences.
IPC_STRUCT_MEMBER(content::RendererPreferences, renderer_preferences)
@@ -460,8 +480,17 @@
// to a view and are only updated by the renderer after this initial value.
IPC_STRUCT_MEMBER(int32, next_page_id)
- // The properties of the screen associated with the view.
- IPC_STRUCT_MEMBER(blink::WebScreenInfo, screen_info)
+ // The initial renderer size.
+ IPC_STRUCT_MEMBER(ViewMsg_Resize_Params, initial_size)
+
+ // Whether to enable auto-resize.
+ IPC_STRUCT_MEMBER(bool, enable_auto_resize)
+
+ // The minimum size to layout the page if auto-resize is enabled.
+ IPC_STRUCT_MEMBER(gfx::Size, min_size)
+
+ // The maximum size to layout the page if auto-resize is enabled.
+ IPC_STRUCT_MEMBER(gfx::Size, max_size)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(ViewMsg_PostMessage_Params)
@@ -564,16 +593,6 @@
// Expects a Close_ACK message when finished.
IPC_MESSAGE_ROUTED0(ViewMsg_Close)
-IPC_STRUCT_BEGIN(ViewMsg_Resize_Params)
- IPC_STRUCT_MEMBER(blink::WebScreenInfo, screen_info)
- IPC_STRUCT_MEMBER(gfx::Size, new_size)
- IPC_STRUCT_MEMBER(gfx::Size, physical_backing_size)
- IPC_STRUCT_MEMBER(float, top_controls_layout_height)
- IPC_STRUCT_MEMBER(gfx::Size, visible_viewport_size)
- IPC_STRUCT_MEMBER(gfx::Rect, resizer_rect)
- IPC_STRUCT_MEMBER(bool, is_fullscreen)
-IPC_STRUCT_END()
-
// Tells the render view to change its size. A ViewHostMsg_UpdateRect message
// is generated in response provided new_size is not empty and not equal to
// the view's current size. The generated ViewHostMsg_UpdateRect message will
diff --git a/content/public/android/java/res/menu/select_action_menu.xml b/content/public/android/java/res/menu/select_action_menu.xml
index 65c729a..3793260 100644
--- a/content/public/android/java/res/menu/select_action_menu.xml
+++ b/content/public/android/java/res/menu/select_action_menu.xml
@@ -37,14 +37,14 @@
/>
<item
android:id="@+id/select_action_menu_share"
- android:icon="@drawable/ic_menu_share_holo_light"
android:title="@string/actionbar_share"
android:showAsAction="always|withText"
+ style="@style/SelectActionMenuShare"
/>
<item
android:id="@+id/select_action_menu_web_search"
- android:icon="@drawable/ic_menu_search_holo_light"
android:title="@string/actionbar_web_search"
android:showAsAction="always|withText"
+ style="@style/SelectActionMenuWebSearch"
/>
</menu>
diff --git a/content/public/android/java/res/values-v17/styles.xml b/content/public/android/java/res/values-v17/styles.xml
index 7c439dc..dbdc8b1 100644
--- a/content/public/android/java/res/values-v17/styles.xml
+++ b/content/public/android/java/res/values-v17/styles.xml
@@ -10,4 +10,10 @@
<item name="select_dialog_singlechoice">@android:layout/select_dialog_singlechoice</item>
<item name="select_dialog_multichoice">@android:layout/select_dialog_multichoice</item>
</style>
+ <style name="SelectActionMenuShare">
+ <item name="android:icon">@drawable/ic_menu_share_holo_light</item>
+ </style>
+ <style name="SelectActionMenuWebSearch">
+ <item name="android:icon">@drawable/ic_menu_search_holo_light</item>
+ </style>
</resources>
diff --git a/content/public/android/java/res/values-v21/styles.xml b/content/public/android/java/res/values-v21/styles.xml
new file mode 100644
index 0000000..a01b0c7
--- /dev/null
+++ b/content/public/android/java/res/values-v21/styles.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+ <style name="SelectActionMenuShare">
+ <item name="android:icon">?android:attr/actionModeShareDrawable</item>
+ </style>
+ <style name="SelectActionMenuWebSearch">
+ <item name="android:icon">?android:attr/actionModeWebSearchDrawable</item>
+ </style>
+</resources>
+
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java b/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java
index 4043988..b2d6e0a 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentVideoView.java
@@ -4,10 +4,8 @@
package org.chromium.content.browser;
-import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.graphics.Point;
import android.provider.Settings;
@@ -231,7 +229,7 @@
mCurrentState = STATE_ERROR;
- if (!isActivityContext(getContext())) {
+ if (ContentViewCore.activityFromContext(getContext()) == null) {
Log.w(TAG, "Unable to show alert dialog because it requires an activity context");
return;
}
@@ -424,16 +422,6 @@
return videoView;
}
- private static boolean isActivityContext(Context context) {
- // Only retrieve the base context if the supplied context is a ContextWrapper but not
- // an Activity, given that Activity is already a subclass of ContextWrapper.
- if (context instanceof ContextWrapper && !(context instanceof Activity)) {
- context = ((ContextWrapper) context).getBaseContext();
- return isActivityContext(context);
- }
- return context instanceof Activity;
- }
-
public void removeSurfaceView() {
removeView(mVideoSurfaceView);
removeView(mProgressView);
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
index 8e4645f..b5bdeaa 100644
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -10,6 +10,7 @@
import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
@@ -358,6 +359,22 @@
public void onSmartClipDataExtracted(String text, String html, Rect clipRect);
}
+ /**
+ * Cast from Context to Activity taking ContextWrapper into account.
+ */
+ public static Activity activityFromContext(Context context) {
+ // Only retrieve the base context if the supplied context is a ContextWrapper but not
+ // an Activity, given that Activity is already a subclass of ContextWrapper.
+ if (context instanceof Activity) {
+ return ((Activity) context);
+ } else if (context instanceof ContextWrapper) {
+ context = ((ContextWrapper) context).getBaseContext();
+ return activityFromContext(context);
+ } else {
+ return null;
+ }
+ }
+
private final Context mContext;
private ViewGroup mContainerView;
private InternalAccessDelegate mContainerViewInternals;
@@ -1930,7 +1947,7 @@
i.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
i.putExtra(SearchManager.QUERY, query);
i.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
- if (!(getContext() instanceof Activity)) {
+ if (activityFromContext(getContext()) == null) {
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
try {
diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java b/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java
index 3035251..25459fb 100644
--- a/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java
+++ b/content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java
@@ -121,6 +121,7 @@
private void createActionMenu(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.select_action_menu, menu);
+
if (!mEditable || !canPaste()) {
menu.removeItem(R.id.select_action_menu_paste);
}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java
index 6745a40..ddc655b 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java
@@ -4,10 +4,15 @@
package org.chromium.content.browser;
+import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
+
import android.test.suitebuilder.annotation.SmallTest;
+import junit.framework.Assert;
+
import org.chromium.base.test.util.Feature;
import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
+import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_shell_apk.ContentShellActivity;
import java.lang.annotation.Annotation;
@@ -16,6 +21,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.ref.WeakReference;
+import java.util.concurrent.CountDownLatch;
/**
* Part of the test suite for the Java Bridge. Tests a number of features including ...
@@ -172,15 +178,27 @@
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
public void testRemovalNotReflectedUntilReload() throws Throwable {
- injectObjectAndReload(new Object(), "testObject");
+ injectObjectAndReload(new Object() {
+ public void method() {
+ mTestController.setStringValue("I'm here");
+ }
+ }, "testObject");
assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
+ executeJavaScript("testObject.method()");
+ assertEquals("I'm here", mTestController.waitForStringValue());
runTestOnUiThread(new Runnable() {
@Override
public void run() {
getContentViewCore().removeJavascriptInterface("testObject");
}
});
+ // Check that the Java object is being held by the Java bridge, thus it's not
+ // collected. Note that despite that what JavaDoc says about invoking "gc()", both Dalvik
+ // and ART actually run the collector if called via Runtime.
+ Runtime.getRuntime().gc();
assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject"));
+ executeJavaScript("testObject.method()");
+ assertEquals("I'm here", mTestController.waitForStringValue());
synchronousPageReload();
assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject"));
}
@@ -521,6 +539,47 @@
@SmallTest
@Feature({"AndroidWebView", "Android-JavaBridge"})
+ public void testBlockingUiThreadDoesNotBlockCallsFromJs() throws Throwable {
+ class TestObject {
+ private CountDownLatch mLatch;
+ public TestObject() {
+ mLatch = new CountDownLatch(1);
+ }
+ public boolean waitOnTheLatch() throws Exception {
+ return mLatch.await(scaleTimeout(10000),
+ java.util.concurrent.TimeUnit.MILLISECONDS);
+ }
+ public void unlockTheLatch() throws Exception {
+ mTestController.setStringValue("unlocked");
+ mLatch.countDown();
+ }
+ }
+ final TestObject testObject = new TestObject();
+ injectObjectAndReload(testObject, "testObject");
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // loadUrl is asynchronous, the JS code will start running on the renderer
+ // thread. As soon as we exit loadUrl, the browser UI thread will be stuck waiting
+ // on the latch. If blocking the browser thread blocks Java Bridge, then the call
+ // to "unlockTheLatch()" will be executed after the waiting timeout, thus the
+ // string value will not yet be updated by the injected object.
+ mTestController.setStringValue("locked");
+ getWebContents().getNavigationController().loadUrl(new LoadUrlParams(
+ "javascript:(function() { testObject.unlockTheLatch() })()"));
+ try {
+ assertTrue(testObject.waitOnTheLatch());
+ } catch (Exception e) {
+ android.util.Log.e("JavaBridgeBasicsTest", "Wait exception", e);
+ Assert.fail("Wait exception");
+ }
+ assertEquals("unlocked", mTestController.getStringValue());
+ }
+ });
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView", "Android-JavaBridge"})
public void testPublicInheritedMethod() throws Throwable {
class Base {
public void method(int x) {
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 728d822..cce349c 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -176,14 +176,6 @@
return NULL;
}
-void ContentBrowserClient::SelectClientCertificate(
- int render_process_id,
- int render_frame_id,
- net::SSLCertRequestInfo* cert_request_info,
- const base::Callback<void(net::X509Certificate*)>& callback) {
- callback.Run(NULL);
-}
-
net::URLRequestContext* ContentBrowserClient::OverrideRequestContextForURL(
const GURL& url, ResourceContext* context) {
return NULL;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 5a27d98..b009696 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -58,6 +58,7 @@
namespace net {
class CookieOptions;
class CookieStore;
+class HttpNetworkSession;
class NetLog;
class SSLCertRequestInfo;
class SSLInfo;
@@ -401,8 +402,9 @@
virtual void SelectClientCertificate(
int render_process_id,
int render_frame_id,
+ const net::HttpNetworkSession* network_session,
net::SSLCertRequestInfo* cert_request_info,
- const base::Callback<void(net::X509Certificate*)>& callback);
+ const base::Callback<void(net::X509Certificate*)>& callback) {}
// Adds a new installable certificate or private key.
// Typically used to install an X.509 user certificate.
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 03c7578..c6e9a4d 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -494,8 +494,8 @@
// pinch gestures.
const char kEnableViewport[] = "enable-viewport";
-// Enables the use of the legacy viewport meta tag. Turning this on also
-// turns on the @viewport CSS rule
+// Enables the viewport meta tag, the de facto way to control layout which works
+// only on mobile browsers.
const char kEnableViewportMeta[] = "enable-viewport-meta";
// Resizes of the main frame are the caused by changing between landscape
diff --git a/content/public/test/content_test_suite_base.cc b/content/public/test/content_test_suite_base.cc
index 9b11678..35226ff 100644
--- a/content/public/test/content_test_suite_base.cc
+++ b/content/public/test/content_test_suite_base.cc
@@ -29,6 +29,7 @@
#include "base/android/jni_android.h"
#include "content/browser/android/browser_jni_registrar.h"
#include "content/common/android/common_jni_registrar.h"
+#include "content/public/browser/android/compositor.h"
#include "media/base/android/media_jni_registrar.h"
#include "net/android/net_jni_registrar.h"
#include "ui/base/android/ui_base_jni_registrar.h"
@@ -80,6 +81,8 @@
net::android::RegisterJni(env);
ui::android::RegisterJni(env);
ui::shell_dialogs::RegisterJni(env);
+
+ content::Compositor::Initialize();
#endif
testing::UnitTest::GetInstance()->listeners().Append(
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc
index 5a86b05..f931461 100644
--- a/content/public/test/render_view_test.cc
+++ b/content/public/test/render_view_test.cc
@@ -204,7 +204,11 @@
false, // hidden
false, // never_visible
1, // next_page_id
- blink::WebScreenInfo());
+ *InitialSizeParams(),
+ false, // enable_auto_resize
+ gfx::Size(), // min_size
+ gfx::Size() // max_size
+ );
view->AddRef();
view_ = view;
}
@@ -407,6 +411,10 @@
return new ContentRendererClient;
}
+scoped_ptr<ViewMsg_Resize_Params> RenderViewTest::InitialSizeParams() {
+ return make_scoped_ptr(new ViewMsg_Resize_Params());
+}
+
void RenderViewTest::GoToOffset(int offset, const PageState& state) {
RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_);
diff --git a/content/public/test/render_view_test.h b/content/public/test/render_view_test.h
index baab05a..46dc35c 100644
--- a/content/public/test/render_view_test.h
+++ b/content/public/test/render_view_test.h
@@ -19,6 +19,8 @@
#include "third_party/WebKit/public/platform/Platform.h"
#include "third_party/WebKit/public/web/WebFrame.h"
+struct ViewMsg_Resize_Params;
+
namespace blink {
class WebWidget;
}
@@ -133,6 +135,9 @@
virtual ContentBrowserClient* CreateContentBrowserClient();
virtual ContentRendererClient* CreateContentRendererClient();
+ // Allows a subclass to customize the initial size of the RenderView.
+ virtual scoped_ptr<ViewMsg_Resize_Params> InitialSizeParams();
+
// testing::Test
void SetUp() override;
diff --git a/content/renderer/media/rtc_data_channel_handler.cc b/content/renderer/media/rtc_data_channel_handler.cc
index 084a020..e37adf3 100644
--- a/content/renderer/media/rtc_data_channel_handler.cc
+++ b/content/renderer/media/rtc_data_channel_handler.cc
@@ -50,7 +50,10 @@
channel_->RegisterObserver(this);
}
-RtcDataChannelHandler::Observer::~Observer() {}
+RtcDataChannelHandler::Observer::~Observer() {
+ DVLOG(3) << "dtor";
+ DCHECK(!channel_.get()) << "Unregister hasn't been called.";
+}
const scoped_refptr<base::SingleThreadTaskRunner>&
RtcDataChannelHandler::Observer::main_thread() const {
@@ -59,12 +62,19 @@
const scoped_refptr<webrtc::DataChannelInterface>&
RtcDataChannelHandler::Observer::channel() const {
+ DCHECK(main_thread_->BelongsToCurrentThread());
return channel_;
}
-void RtcDataChannelHandler::Observer::ClearHandler() {
+void RtcDataChannelHandler::Observer::Unregister() {
DCHECK(main_thread_->BelongsToCurrentThread());
handler_ = nullptr;
+ if (channel_.get()) {
+ channel_->UnregisterObserver();
+ // Now that we're guaranteed to not get further OnStateChange callbacks,
+ // it's safe to release our reference to the channel.
+ channel_ = nullptr;
+ }
}
void RtcDataChannelHandler::Observer::OnStateChange() {
@@ -127,13 +137,18 @@
RtcDataChannelHandler::~RtcDataChannelHandler() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "::dtor";
- observer_->ClearHandler();
+ DCHECK(!observer_.get());
}
void RtcDataChannelHandler::setClient(
blink::WebRTCDataChannelHandlerClient* client) {
DCHECK(thread_checker_.CalledOnValidThread());
+ DVLOG(3) << "setClient " << client;
webkit_client_ = client;
+ if (!client) {
+ observer_->Unregister();
+ observer_ = nullptr;
+ }
}
blink::WebString RtcDataChannelHandler::label() {
@@ -273,6 +288,7 @@
}
void RtcDataChannelHandler::RecordMessageSent(size_t num_bytes) {
+ DCHECK(thread_checker_.CalledOnValidThread());
// Currently, messages are capped at some fairly low limit (16 Kb?)
// but we may allow unlimited-size messages at some point, so making
// the histogram maximum quite large (100 Mb) to have some
diff --git a/content/renderer/media/rtc_data_channel_handler.h b/content/renderer/media/rtc_data_channel_handler.h
index 79addde..efcec2d 100644
--- a/content/renderer/media/rtc_data_channel_handler.h
+++ b/content/renderer/media/rtc_data_channel_handler.h
@@ -74,7 +74,10 @@
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread() const;
const scoped_refptr<webrtc::DataChannelInterface>& channel() const;
- void ClearHandler();
+ // Clears the internal |handler_| pointer so that no further callbacks
+ // will be attempted, disassociates this observer from the channel and
+ // releases the channel pointer. Must be called on the main thread.
+ void Unregister();
private:
friend class base::RefCountedThreadSafe<RtcDataChannelHandler::Observer>;
@@ -89,7 +92,7 @@
RtcDataChannelHandler* handler_;
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<webrtc::DataChannelInterface> channel_;
+ scoped_refptr<webrtc::DataChannelInterface> channel_;
};
scoped_refptr<Observer> observer_;
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index 2ee286a..3bcda49 100644
--- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -966,6 +966,7 @@
pc_handler_->createDataChannel("d1", blink::WebRTCDataChannelInit()));
EXPECT_TRUE(channel.get() != NULL);
EXPECT_EQ(label, channel->label());
+ channel->setClient(nullptr);
}
TEST_F(RTCPeerConnectionHandlerTest, CreateDtmfSender) {
diff --git a/content/renderer/media/webrtc/media_stream_track_metrics.cc b/content/renderer/media/webrtc/media_stream_track_metrics.cc
index d4ce6b4..d6962c3 100644
--- a/content/renderer/media/webrtc/media_stream_track_metrics.cc
+++ b/content/renderer/media/webrtc/media_stream_track_metrics.cc
@@ -9,6 +9,7 @@
#include <string>
#include "base/md5.h"
+#include "base/thread_task_runner_handle.h"
#include "content/common/media/media_stream_track_metrics_host_messages.h"
#include "content/renderer/render_thread_impl.h"
#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
@@ -20,37 +21,102 @@
using webrtc::VideoTrackVector;
namespace content {
+namespace {
+typedef std::set<std::string> IdSet;
-class MediaStreamTrackMetricsObserver : public webrtc::ObserverInterface {
+template <class T>
+IdSet GetTrackIds(const std::vector<rtc::scoped_refptr<T>>& tracks) {
+ IdSet track_ids;
+ for (const auto& track : tracks)
+ track_ids.insert(track->id());
+ return track_ids;
+}
+
+// TODO(tommi): Consolidate this and TrackObserver since these implementations
+// are fundamentally achieving the same thing (aside from specific logic inside
+// the OnChanged callbacks).
+class MediaStreamObserver
+ : public base::RefCountedThreadSafe<MediaStreamObserver>,
+ public webrtc::ObserverInterface {
+ public:
+ typedef base::Callback<
+ void(const IdSet& audio_track_ids, const IdSet& video_track_ids)>
+ OnChangedCallback;
+
+ MediaStreamObserver(
+ const OnChangedCallback& callback,
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
+ webrtc::MediaStreamInterface* stream)
+ : main_thread_(main_thread), stream_(stream), callback_(callback) {
+ signaling_thread_.DetachFromThread();
+ stream_->RegisterObserver(this);
+ }
+
+ const scoped_refptr<webrtc::MediaStreamInterface>& stream() const {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ return stream_;
+ }
+
+ void Unregister() {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ callback_.Reset();
+ stream_->UnregisterObserver(this);
+ stream_ = nullptr;
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<MediaStreamObserver>;
+ ~MediaStreamObserver() override {
+ DCHECK(!stream_.get()) << "must have been unregistered before deleting";
+ }
+
+ // webrtc::ObserverInterface implementation.
+ void OnChanged() override {
+ DCHECK(signaling_thread_.CalledOnValidThread());
+ main_thread_->PostTask(FROM_HERE,
+ base::Bind(&MediaStreamObserver::OnChangedOnMainThread, this,
+ GetTrackIds(stream_->GetAudioTracks()),
+ GetTrackIds(stream_->GetVideoTracks())));
+ }
+
+ void OnChangedOnMainThread(const IdSet& audio_track_ids,
+ const IdSet& video_track_ids) {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ if (!callback_.is_null())
+ callback_.Run(audio_track_ids, video_track_ids);
+ }
+
+ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
+ scoped_refptr<webrtc::MediaStreamInterface> stream_;
+ OnChangedCallback callback_; // Only touched on the main thread.
+ base::ThreadChecker signaling_thread_;
+};
+
+} // namespace
+
+class MediaStreamTrackMetricsObserver {
public:
MediaStreamTrackMetricsObserver(
MediaStreamTrackMetrics::StreamType stream_type,
MediaStreamInterface* stream,
MediaStreamTrackMetrics* owner);
- ~MediaStreamTrackMetricsObserver() override;
+ ~MediaStreamTrackMetricsObserver();
// Sends begin/end messages for all tracks currently tracked.
void SendLifetimeMessages(MediaStreamTrackMetrics::LifetimeEvent event);
- MediaStreamInterface* stream() { return stream_; }
- MediaStreamTrackMetrics::StreamType stream_type() { return stream_type_; }
+ MediaStreamInterface* stream() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return observer_->stream().get();
+ }
+
+ MediaStreamTrackMetrics::StreamType stream_type() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return stream_type_;
+ }
private:
- typedef std::set<std::string> IdSet;
-
- // webrtc::ObserverInterface implementation.
- void OnChanged() override;
-
- template <class T>
- IdSet GetTrackIds(const std::vector<rtc::scoped_refptr<T> >& tracks) {
- IdSet track_ids;
- typename std::vector<rtc::scoped_refptr<T> >::const_iterator it =
- tracks.begin();
- for (; it != tracks.end(); ++it) {
- track_ids.insert((*it)->id());
- }
- return track_ids;
- }
+ void OnChanged(const IdSet& audio_track_ids, const IdSet& video_track_ids);
void ReportAddedAndRemovedTracks(
const IdSet& new_ids,
@@ -72,10 +138,11 @@
IdSet video_track_ids_;
MediaStreamTrackMetrics::StreamType stream_type_;
- rtc::scoped_refptr<MediaStreamInterface> stream_;
+ scoped_refptr<MediaStreamObserver> observer_;
// Non-owning.
MediaStreamTrackMetrics* owner_;
+ base::ThreadChecker thread_checker_;
};
namespace {
@@ -101,20 +168,26 @@
MediaStreamTrackMetrics* owner)
: has_reported_start_(false),
has_reported_end_(false),
+ audio_track_ids_(GetTrackIds(stream->GetAudioTracks())),
+ video_track_ids_(GetTrackIds(stream->GetVideoTracks())),
stream_type_(stream_type),
- stream_(stream),
+ observer_(new MediaStreamObserver(
+ base::Bind(&MediaStreamTrackMetricsObserver::OnChanged,
+ base::Unretained(this)),
+ base::ThreadTaskRunnerHandle::Get(),
+ stream)),
owner_(owner) {
- OnChanged(); // To populate initial tracks.
- stream_->RegisterObserver(this);
}
MediaStreamTrackMetricsObserver::~MediaStreamTrackMetricsObserver() {
- stream_->UnregisterObserver(this);
+ DCHECK(thread_checker_.CalledOnValidThread());
+ observer_->Unregister();
SendLifetimeMessages(MediaStreamTrackMetrics::DISCONNECTED);
}
void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
MediaStreamTrackMetrics::LifetimeEvent event) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (event == MediaStreamTrackMetrics::CONNECTED) {
// Both ICE CONNECTED and COMPLETED can trigger the first
// start-of-life event, so we only report the first.
@@ -146,33 +219,31 @@
}
}
-void MediaStreamTrackMetricsObserver::OnChanged() {
- AudioTrackVector all_audio_tracks = stream_->GetAudioTracks();
- IdSet all_audio_track_ids = GetTrackIds(all_audio_tracks);
-
- VideoTrackVector all_video_tracks = stream_->GetVideoTracks();
- IdSet all_video_track_ids = GetTrackIds(all_video_tracks);
+void MediaStreamTrackMetricsObserver::OnChanged(
+ const IdSet& audio_track_ids, const IdSet& video_track_ids) {
+ DCHECK(thread_checker_.CalledOnValidThread());
// We only report changes after our initial report, and never after
// our last report.
if (has_reported_start_ && !has_reported_end_) {
- ReportAddedAndRemovedTracks(all_audio_track_ids,
+ ReportAddedAndRemovedTracks(audio_track_ids,
audio_track_ids_,
MediaStreamTrackMetrics::AUDIO_TRACK);
- ReportAddedAndRemovedTracks(all_video_track_ids,
+ ReportAddedAndRemovedTracks(video_track_ids,
video_track_ids_,
MediaStreamTrackMetrics::VIDEO_TRACK);
}
// We always update our sets of tracks.
- audio_track_ids_ = all_audio_track_ids;
- video_track_ids_ = all_video_track_ids;
+ audio_track_ids_ = audio_track_ids;
+ video_track_ids_ = video_track_ids;
}
void MediaStreamTrackMetricsObserver::ReportAddedAndRemovedTracks(
const IdSet& new_ids,
const IdSet& old_ids,
MediaStreamTrackMetrics::TrackType track_type) {
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(has_reported_start_ && !has_reported_end_);
IdSet added_tracks = base::STLSetDifference<IdSet>(new_ids, old_ids);
@@ -187,6 +258,7 @@
const IdSet& ids,
MediaStreamTrackMetrics::TrackType track_type,
MediaStreamTrackMetrics::LifetimeEvent event) {
+ DCHECK(thread_checker_.CalledOnValidThread());
for (IdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
owner_->SendLifetimeMessage(*it, track_type, event, stream_type_);
}
diff --git a/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc b/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
index dcf1b13..d18c04f 100644
--- a/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
+++ b/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/threading/thread.h"
#include "content/renderer/media/webrtc/media_stream_track_metrics.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -78,16 +82,56 @@
class MediaStreamTrackMetricsTest : public testing::Test {
public:
+ MediaStreamTrackMetricsTest() : signaling_thread_("signaling_thread") {}
void SetUp() override {
metrics_.reset(new MockMediaStreamTrackMetrics());
stream_ = new rtc::RefCountedObject<MockMediaStream>("stream");
+ signaling_thread_.Start();
}
void TearDown() override {
+ signaling_thread_.Stop();
metrics_.reset();
stream_ = NULL;
}
+ // Adds an audio track to |stream_| on the signaling thread to simulate how
+ // notifications will be fired in Chrome.
+ template <typename TrackType>
+ void AddTrack(TrackType* track) {
+ // Explicitly casting to this type is necessary since the
+ // MediaStreamInterface has two methods with the same name.
+ typedef bool (MediaStreamInterface::*AddTrack)(TrackType*);
+ base::RunLoop run_loop;
+ signaling_thread_.task_runner()->PostTaskAndReply(FROM_HERE,
+ base::Bind(
+ base::IgnoreResult<AddTrack>(&MediaStreamInterface::AddTrack),
+ stream_, track),
+ run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ template <typename TrackType>
+ void RemoveTrack(TrackType* track) {
+ // Explicitly casting to this type is necessary since the
+ // MediaStreamInterface has two methods with the same name.
+ typedef bool (MediaStreamInterface::*RemoveTrack)(TrackType*);
+ base::RunLoop run_loop;
+ signaling_thread_.task_runner()->PostTaskAndReply(FROM_HERE,
+ base::Bind(
+ base::IgnoreResult<RemoveTrack>(&MediaStreamInterface::RemoveTrack),
+ stream_, track),
+ run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ // Convenience methods to cast the mock track types into their webrtc
+ // equivalents.
+ void AddAudioTrack(AudioTrackInterface* track) { AddTrack(track); }
+ void RemoveAudioTrack(AudioTrackInterface* track) { RemoveTrack(track); }
+ void AddVideoTrack(VideoTrackInterface* track) { AddTrack(track); }
+ void RemoveVideoTrack(VideoTrackInterface* track) { RemoveTrack(track); }
+
scoped_refptr<MockAudioTrackInterface> MakeAudioTrack(std::string id) {
return new rtc::RefCountedObject<MockAudioTrackInterface>(id);
}
@@ -98,6 +142,9 @@
scoped_ptr<MockMediaStreamTrackMetrics> metrics_;
scoped_refptr<MediaStreamInterface> stream_;
+
+ base::MessageLoopForUI message_loop_;
+ base::Thread signaling_thread_;
};
TEST_F(MediaStreamTrackMetricsTest, MakeUniqueId) {
@@ -262,7 +309,7 @@
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::RECEIVED_STREAM));
- stream_->AddTrack(added.get());
+ AddAudioTrack(added.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("initial",
@@ -321,7 +368,7 @@
// This gets added after we start observing, but no lifetime message
// should be sent at this point since the call is not connected. It
// should get sent only once it gets connected.
- stream_->AddTrack(second.get());
+ AddAudioTrack(second.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("first",
@@ -350,7 +397,7 @@
// This happens after the call is disconnected so no lifetime
// message should be sent.
- stream_->RemoveTrack(first.get());
+ RemoveAudioTrack(first.get());
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamMultipleDisconnects) {
@@ -374,7 +421,7 @@
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
- stream_->RemoveTrack(audio.get());
+ RemoveAudioTrack(audio.get());
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamConnectDisconnectTwice) {
@@ -400,7 +447,7 @@
PeerConnectionInterface::kIceConnectionDisconnected);
}
- stream_->RemoveTrack(audio.get());
+ RemoveAudioTrack(audio.get());
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamRemovedNoDisconnect) {
@@ -465,33 +512,33 @@
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->AddTrack(audio2.get());
+ AddAudioTrack(audio2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video2",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->AddTrack(video2.get());
+ AddVideoTrack(video2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio1",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(audio1.get());
+ RemoveAudioTrack(audio1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio3",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->AddTrack(audio3.get());
+ AddAudioTrack(audio3.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video3",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->AddTrack(video3.get());
+ AddVideoTrack(video3.get());
// Add back audio1
EXPECT_CALL(*metrics_,
@@ -499,33 +546,33 @@
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::CONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->AddTrack(audio1.get());
+ AddAudioTrack(audio1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio2",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(audio2.get());
+ RemoveAudioTrack(audio2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video2",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(video2.get());
+ RemoveVideoTrack(video2.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio1",
MediaStreamTrackMetrics::AUDIO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(audio1.get());
+ RemoveAudioTrack(audio1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("video1",
MediaStreamTrackMetrics::VIDEO_TRACK,
MediaStreamTrackMetrics::DISCONNECTED,
MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(video1.get());
+ RemoveVideoTrack(video1.get());
EXPECT_CALL(*metrics_,
SendLifetimeMessage("audio3",
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
index 1bc3c05..e203c60 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -174,7 +174,8 @@
}
PeerConnectionDependencyFactory::~PeerConnectionDependencyFactory() {
- CleanupPeerConnectionFactory();
+ DVLOG(1) << "~PeerConnectionDependencyFactory()";
+ DCHECK(pc_factory_.get() == NULL);
if (aec_dump_message_filter_.get())
aec_dump_message_filter_->RemoveDelegate(this);
}
@@ -268,6 +269,11 @@
return pc_factory_;
}
+
+void PeerConnectionDependencyFactory::WillDestroyCurrentMessageLoop() {
+ CleanupPeerConnectionFactory();
+}
+
void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() {
DCHECK(!pc_factory_.get());
DCHECK(!signaling_thread_);
@@ -279,6 +285,7 @@
DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()";
+ base::MessageLoop::current()->AddDestructionObserver(this);
// To allow sending to the signaling/worker threads.
jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop();
jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true);
@@ -584,6 +591,7 @@
}
void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() {
+ DVLOG(1) << "PeerConnectionDependencyFactory::CleanupPeerConnectionFactory()";
pc_factory_ = NULL;
if (network_manager_) {
// The network manager needs to free its resources on the thread they were
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index 67eae9d..07375dd 100644
--- a/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "base/files/file.h"
+#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "content/common/content_export.h"
#include "content/public/renderer/render_process_observer.h"
@@ -56,6 +57,7 @@
// Object factory for RTC PeerConnections.
class CONTENT_EXPORT PeerConnectionDependencyFactory
: NON_EXPORTED_BASE(public base::NonThreadSafe),
+ NON_EXPORTED_BASE(base::MessageLoop::DestructionObserver),
NON_EXPORTED_BASE(public AecDumpMessageFilter::AecDumpDelegate) {
public:
PeerConnectionDependencyFactory(
@@ -170,6 +172,11 @@
virtual void StartLocalAudioTrack(WebRtcLocalAudioTrack* audio_track);
private:
+ // Implement base::MessageLoop::DestructionObserver.
+ // This makes sure the libjingle PeerConnectionFactory is released before
+ // the renderer message loop is destroyed.
+ virtual void WillDestroyCurrentMessageLoop() override;
+
// Creates |pc_factory_|, which in turn is used for
// creating PeerConnection objects.
void CreatePeerConnectionFactory();
diff --git a/content/renderer/media/webrtc/video_destination_handler.cc b/content/renderer/media/webrtc/video_destination_handler.cc
index 6e25469..0e2ba8e 100644
--- a/content/renderer/media/webrtc/video_destination_handler.cc
+++ b/content/renderer/media/webrtc/video_destination_handler.cc
@@ -157,16 +157,24 @@
MediaStreamVideoSource::kUnknownFrameRate,
media::PIXEL_FORMAT_YV12);
- libyuv::ARGBToI420(src_data,
- src_stride,
- new_frame->data(media::VideoFrame::kYPlane),
- new_frame->stride(media::VideoFrame::kYPlane),
- new_frame->data(media::VideoFrame::kUPlane),
- new_frame->stride(media::VideoFrame::kUPlane),
- new_frame->data(media::VideoFrame::kVPlane),
- new_frame->stride(media::VideoFrame::kVPlane),
- width,
- height);
+ // TODO(magjed): Chrome OS is not ready for switching from BGRA to ARGB.
+ // Remove this once http://crbug/434007 is fixed. We have a corresponding
+ // problem when we send frames to the effects plugin in PepperVideoSourceHost.
+#if defined(OS_CHROMEOS)
+ auto libyuv_xxxx_to_i420 = &libyuv::BGRAToI420;
+#else
+ auto libyuv_xxxx_to_i420 = &libyuv::ARGBToI420;
+#endif
+ libyuv_xxxx_to_i420(src_data,
+ src_stride,
+ new_frame->data(media::VideoFrame::kYPlane),
+ new_frame->stride(media::VideoFrame::kYPlane),
+ new_frame->data(media::VideoFrame::kUPlane),
+ new_frame->stride(media::VideoFrame::kUPlane),
+ new_frame->data(media::VideoFrame::kVPlane),
+ new_frame->stride(media::VideoFrame::kVPlane),
+ width,
+ height);
delegate_->DeliverFrame(new_frame, format);
}
diff --git a/content/renderer/pepper/pepper_video_source_host.cc b/content/renderer/pepper/pepper_video_source_host.cc
index b75eabb..49efee2 100644
--- a/content/renderer/pepper/pepper_video_source_host.cc
+++ b/content/renderer/pepper/pepper_video_source_host.cc
@@ -224,16 +224,24 @@
const uint8* src_v = frame->data(media::VideoFrame::kVPlane) +
(center * vert_crop + horiz_crop) / 2;
- libyuv::I420ToARGB(src_y,
- frame->stride(media::VideoFrame::kYPlane),
- src_u,
- frame->stride(media::VideoFrame::kUPlane),
- src_v,
- frame->stride(media::VideoFrame::kVPlane),
- bitmap_pixels,
- bitmap->rowBytes(),
- dst_width,
- dst_height);
+ // TODO(magjed): Chrome OS is not ready for switching from BGRA to ARGB.
+ // Remove this once http://crbug/434007 is fixed. We have a corresponding
+ // problem when we receive frames from the effects plugin in PpFrameWriter.
+#if defined(OS_CHROMEOS)
+ auto libyuv_i420_to_xxxx = &libyuv::I420ToBGRA;
+#else
+ auto libyuv_i420_to_xxxx = &libyuv::I420ToARGB;
+#endif
+ libyuv_i420_to_xxxx(src_y,
+ frame->stride(media::VideoFrame::kYPlane),
+ src_u,
+ frame->stride(media::VideoFrame::kUPlane),
+ src_v,
+ frame->stride(media::VideoFrame::kVPlane),
+ bitmap_pixels,
+ bitmap->rowBytes(),
+ dst_width,
+ dst_height);
ppapi::HostResource host_resource;
host_resource.SetHostResource(pp_instance(), shared_image_->GetReference());
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 6984b13..713dffd 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -623,8 +623,11 @@
#if defined(ENABLE_WEBRTC)
RTCPeerConnectionHandler::DestructAllHandlers();
-
- peer_connection_factory_.reset();
+ // |peer_connection_factory_| cannot be deleted until after the main message
+ // loop has been destroyed. This is because there may be pending tasks that
+ // hold on to objects produced by the PC factory that depend on threads owned
+ // by the PC factory. Once those tasks have been freed, the factory can be
+ // deleted.
#endif
RemoveFilter(vc_manager_->video_capture_message_filter());
vc_manager_.reset();
@@ -1345,7 +1348,10 @@
params.hidden,
params.never_visible,
params.next_page_id,
- params.screen_info);
+ params.initial_size,
+ params.enable_auto_resize,
+ params.min_size,
+ params.max_size);
}
GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc
index 7dc2da8..bc75a42 100644
--- a/content/renderer/render_view_browsertest.cc
+++ b/content/renderer/render_view_browsertest.cc
@@ -2494,4 +2494,25 @@
EXPECT_LE(late_nav_reported_start, after_navigation);
}
+class RenderViewImplInitialSizeTest : public RenderViewImplTest {
+ public:
+ RenderViewImplInitialSizeTest()
+ : RenderViewImplTest(), initial_size_(200, 100) {}
+
+ protected:
+ virtual scoped_ptr<ViewMsg_Resize_Params> InitialSizeParams() override {
+ scoped_ptr<ViewMsg_Resize_Params> initial_size_params(
+ new ViewMsg_Resize_Params());
+ initial_size_params->new_size = initial_size_;
+ return initial_size_params.Pass();
+ }
+
+ gfx::Size initial_size_;
+};
+
+TEST_F(RenderViewImplInitialSizeTest, InitialSize) {
+ ASSERT_EQ(initial_size_, view_->GetSize());
+ ASSERT_EQ(initial_size_, gfx::Size(view_->GetWebView()->size()));
+}
+
} // namespace content
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 56a719e..6897573 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -643,7 +643,7 @@
RenderViewImpl::RenderViewImpl(RenderViewImplParams* params)
: RenderWidget(blink::WebPopupTypeNone,
- params->screen_info,
+ params->initial_size.screen_info,
params->swapped_out,
params->hidden,
params->never_visible),
@@ -790,6 +790,12 @@
OnSetRendererPrefs(params->renderer_prefs);
+ if (!params->enable_auto_resize) {
+ OnResize(params->initial_size);
+ } else {
+ OnEnableAutoResize(params->min_size, params->max_size);
+ }
+
new MHTMLGenerator(this);
#if defined(OS_MACOSX)
new TextInputClientObserver(this);
@@ -1142,7 +1148,10 @@
bool hidden,
bool never_visible,
int32 next_page_id,
- const blink::WebScreenInfo& screen_info) {
+ const ViewMsg_Resize_Params& initial_size,
+ bool enable_auto_resize,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size) {
DCHECK(routing_id != MSG_ROUTING_NONE);
RenderViewImplParams params(opener_id,
window_was_created_with_opener,
@@ -1159,7 +1168,10 @@
hidden,
never_visible,
next_page_id,
- screen_info);
+ initial_size,
+ enable_auto_resize,
+ min_size,
+ max_size);
RenderViewImpl* render_view = NULL;
if (g_create_render_view_impl)
render_view = g_create_render_view_impl(¶ms);
@@ -1672,6 +1684,9 @@
// TODO(vangelis): Can we tell if the new view will be a background page?
bool never_visible = false;
+ ViewMsg_Resize_Params initial_size = ViewMsg_Resize_Params();
+ initial_size.screen_info = screen_info_;
+
// The initial hidden state for the RenderViewImpl here has to match what the
// browser will eventually decide for the given disposition. Since we have to
// return from this call synchronously, we just have to make our best guess
@@ -1693,7 +1708,11 @@
params.disposition == NEW_BACKGROUND_TAB, // hidden
never_visible,
1, // next_page_id
- screen_info_);
+ initial_size,
+ false, // enable_auto_resize
+ gfx::Size(), // min_size
+ gfx::Size() // max_size
+ );
view->opened_by_user_gesture_ = params.user_gesture;
// Record whether the creator frame is trying to suppress the opener field.
@@ -4045,6 +4064,9 @@
const WebSize& inner_viewport_offset,
const WebRect& touch_rect,
const WebVector<WebRect>& target_rects) {
+ if (!switches::IsLinkDisambiguationPopupEnabled())
+ return false;
+
// Never show a disambiguation popup when accessibility is enabled,
// as this interferes with "touch exploration".
AccessibilityMode accessibility_mode =
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 67adc19..be982b0 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -78,6 +78,7 @@
struct PP_NetAddress_Private;
struct FrameMsg_Navigate_Params;
struct ViewMsg_PostMessage_Params;
+struct ViewMsg_Resize_Params;
struct ViewMsg_StopFinding_Params;
namespace base {
@@ -178,7 +179,10 @@
bool hidden,
bool never_visible,
int32 next_page_id,
- const blink::WebScreenInfo& screen_info);
+ const ViewMsg_Resize_Params& initial_size,
+ bool enable_auto_resize,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size);
// Used by content_layouttest_support to hook into the creation of
// RenderViewImpls.
diff --git a/content/renderer/render_view_impl_params.cc b/content/renderer/render_view_impl_params.cc
index 6864a3d..5a39b4c 100644
--- a/content/renderer/render_view_impl_params.cc
+++ b/content/renderer/render_view_impl_params.cc
@@ -22,7 +22,10 @@
bool hidden,
bool never_visible,
int32 next_page_id,
- const blink::WebScreenInfo& screen_info)
+ const ViewMsg_Resize_Params& initial_size,
+ bool enable_auto_resize,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size)
: opener_id(opener_id),
window_was_created_with_opener(window_was_created_with_opener),
renderer_prefs(renderer_prefs),
@@ -38,7 +41,10 @@
hidden(hidden),
never_visible(never_visible),
next_page_id(next_page_id),
- screen_info(screen_info) {}
+ initial_size(initial_size),
+ enable_auto_resize(enable_auto_resize),
+ min_size(min_size),
+ max_size(max_size) {}
RenderViewImplParams::~RenderViewImplParams() {}
diff --git a/content/renderer/render_view_impl_params.h b/content/renderer/render_view_impl_params.h
index ad9a26c..173b6a4 100644
--- a/content/renderer/render_view_impl_params.h
+++ b/content/renderer/render_view_impl_params.h
@@ -9,7 +9,9 @@
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
#include "content/common/content_export.h"
-#include "content/common/view_message_enums.h"
+#include "ui/gfx/geometry/size.h"
+
+struct ViewMsg_Resize_Params;
namespace blink {
struct WebScreenInfo;
@@ -37,7 +39,10 @@
bool hidden,
bool never_visible,
int32 next_page_id,
- const blink::WebScreenInfo& screen_info);
+ const ViewMsg_Resize_Params& initial_size,
+ bool enable_auto_resize,
+ const gfx::Size& min_size,
+ const gfx::Size& max_size);
~RenderViewImplParams();
int32 opener_id;
@@ -55,7 +60,10 @@
bool hidden;
bool never_visible;
int32 next_page_id;
- const blink::WebScreenInfo& screen_info;
+ const ViewMsg_Resize_Params& initial_size;
+ bool enable_auto_resize;
+ gfx::Size min_size;
+ gfx::Size max_size;
};
} // namespace content
diff --git a/content/shell/renderer/test_runner/event_sender.cc b/content/shell/renderer/test_runner/event_sender.cc
index 4c90eb4..c16eba0 100644
--- a/content/shell/renderer/test_runner/event_sender.cc
+++ b/content/shell/renderer/test_runner/event_sender.cc
@@ -357,6 +357,7 @@
void ZoomPageOut();
void SetPageZoomFactor(double factor);
void SetPageScaleFactor(gin::Arguments* args);
+ void SetPageScaleFactorLimits(gin::Arguments* args);
void ClearTouchPoints();
void ReleaseTouchPoint(unsigned index);
void UpdateTouchPoint(unsigned index, double x, double y);
@@ -483,6 +484,8 @@
.SetMethod("zoomPageOut", &EventSenderBindings::ZoomPageOut)
.SetMethod("setPageZoomFactor", &EventSenderBindings::SetPageZoomFactor)
.SetMethod("setPageScaleFactor", &EventSenderBindings::SetPageScaleFactor)
+ .SetMethod("setPageScaleFactorLimits",
+ &EventSenderBindings::SetPageScaleFactorLimits)
.SetMethod("clearTouchPoints", &EventSenderBindings::ClearTouchPoints)
.SetMethod("releaseTouchPoint", &EventSenderBindings::ReleaseTouchPoint)
.SetMethod("updateTouchPoint", &EventSenderBindings::UpdateTouchPoint)
@@ -640,6 +643,20 @@
static_cast<int>(x), static_cast<int>(y));
}
+void EventSenderBindings::SetPageScaleFactorLimits(gin::Arguments* args) {
+ if (!sender_)
+ return;
+ float min_scale_factor;
+ float max_scale_factor;
+ if (args->PeekNext().IsEmpty())
+ return;
+ args->GetNext(&min_scale_factor);
+ if (args->PeekNext().IsEmpty())
+ return;
+ args->GetNext(&max_scale_factor);
+ sender_->SetPageScaleFactorLimits(min_scale_factor, max_scale_factor);
+}
+
void EventSenderBindings::ClearTouchPoints() {
if (sender_)
sender_->ClearTouchPoints();
@@ -1463,10 +1480,13 @@
}
void EventSender::SetPageScaleFactor(float scale_factor, int x, int y) {
- view_->setPageScaleFactorLimits(scale_factor, scale_factor);
view_->setPageScaleFactor(scale_factor, WebPoint(x, y));
}
+void EventSender::SetPageScaleFactorLimits(float min_scale, float max_scale) {
+ view_->setPageScaleFactorLimits(min_scale, max_scale);
+}
+
void EventSender::ClearTouchPoints() {
touch_points_.clear();
}
diff --git a/content/shell/renderer/test_runner/event_sender.h b/content/shell/renderer/test_runner/event_sender.h
index 2d4b99a..71f72d7 100644
--- a/content/shell/renderer/test_runner/event_sender.h
+++ b/content/shell/renderer/test_runner/event_sender.h
@@ -99,7 +99,10 @@
void ZoomPageOut();
void SetPageZoomFactor(double zoom_factor);
+ // TODO: Move these into Internals once PageScaleConstraints are moved out of
+ // Source/web. crbug.com/434450.
void SetPageScaleFactor(float scale_factor, int x, int y);
+ void SetPageScaleFactorLimits(float min_scale, float max_scale);
void ClearTouchPoints();
void ReleaseTouchPoint(unsigned index);
diff --git a/content/test/run_all_unittests.cc b/content/test/run_all_unittests.cc
index b6170ad..9c86597 100644
--- a/content/test/run_all_unittests.cc
+++ b/content/test/run_all_unittests.cc
@@ -8,7 +8,16 @@
#include "content/public/test/unittest_test_suite.h"
#include "content/test/content_test_suite.h"
+#if defined(OS_ANDROID)
+#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#endif
+
int main(int argc, char** argv) {
+#if defined(OS_ANDROID)
+ // Android wants to call GetChannelId() (even though GPU channels
+ // are not getting created in content_unittests).
+ content::BrowserGpuChannelHostFactory::Initialize(false);
+#endif
#if !defined(OS_IOS)
content::InitializeMojo();
#endif
diff --git a/device/usb/usb_device_impl.cc b/device/usb/usb_device_impl.cc
index 57f3d63..6fa3d50 100644
--- a/device/usb/usb_device_impl.cc
+++ b/device/usb/usb_device_impl.cc
@@ -157,6 +157,12 @@
continue;
}
+#if defined(OS_CHROMEOS)
+ value = udev_device_get_devnode(device.get());
+ if (value) {
+ devnode_ = value;
+ }
+#endif
value = udev_device_get_sysattr_value(device.get(), "manufacturer");
if (value) {
manufacturer_ = base::UTF8ToUTF16(value);
@@ -207,10 +213,9 @@
ui_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&chromeos::PermissionBrokerClient::RequestUsbAccess,
+ base::Bind(&chromeos::PermissionBrokerClient::RequestPathAccess,
base::Unretained(client),
- vendor_id(),
- product_id(),
+ devnode_,
interface_id,
base::Bind(&OnRequestUsbAccessReplied,
base::ThreadTaskRunnerHandle::Get(),
diff --git a/device/usb/usb_device_impl.h b/device/usb/usb_device_impl.h
index e962c6d..379d401 100644
--- a/device/usb/usb_device_impl.h
+++ b/device/usb/usb_device_impl.h
@@ -76,6 +76,11 @@
void CacheStrings();
bool strings_cached_;
#endif
+#if defined(OS_CHROMEOS)
+ // On Chrome OS save the devnode string for requesting path access from
+ // permission broker.
+ std::string devnode_;
+#endif
// The active configuration descriptor is not read immediately but cached for
// later use.
diff --git a/extensions/browser/guest_view/guest_view_base.cc b/extensions/browser/guest_view/guest_view_base.cc
index 01c7a5e..6679985 100644
--- a/extensions/browser/guest_view/guest_view_base.cc
+++ b/extensions/browser/guest_view/guest_view_base.cc
@@ -419,12 +419,6 @@
void GuestViewBase::RenderViewReady() {
GuestReady();
- content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
- if (auto_size_enabled_) {
- rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
- } else {
- rvh->DisableAutoResize(element_size_);
- }
}
void GuestViewBase::WebContentsDestroyed() {
diff --git a/extensions/common/api/_api_features.json b/extensions/common/api/_api_features.json
index 262bae2..52ac29c 100644
--- a/extensions/common/api/_api_features.json
+++ b/extensions/common/api/_api_features.json
@@ -76,9 +76,12 @@
"contexts": ["blessed_extension"],
"dependencies": ["permission:appview"]
},
+ // Note that exposing this doesn't necessarily expose AppView,
+ // appViewEmbedderInternal is required for that.
+ // See http://crbug.com/437891.
"appViewGuestInternal": {
"internal": true,
- "channel": "dev",
+ "channel": "stable",
"contexts": ["blessed_extension"]
},
"bluetooth": {
diff --git a/extensions/test/data/web_view/apitest/main.js b/extensions/test/data/web_view/apitest/main.js
index 2c8d15f..977b063 100644
--- a/extensions/test/data/web_view/apitest/main.js
+++ b/extensions/test/data/web_view/apitest/main.js
@@ -222,8 +222,6 @@
webview.setAttribute('maxheight', 110);
webview.addEventListener('sizechanged', function(e) {
- embedder.test.assertEq(0, e.oldWidth);
- embedder.test.assertEq(0, e.oldHeight);
embedder.test.assertTrue(e.newWidth >= 200 && e.newWidth <= 210);
embedder.test.assertTrue(e.newHeight >= 100 && e.newHeight <= 110);
embedder.test.succeed();
@@ -248,7 +246,6 @@
webview.addEventListener('sizechanged', function(e) {
switch (step) {
case 1:
- embedder.test.assertEq(0, e.oldHeight);
embedder.test.assertEq(200, e.newHeight);
// Change the maxheight to verify that we see the change.
webview.maxheight = 50;
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index e1e9650..120e6db 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
{
"name": "gpu driver bug list",
// Please update the version number whenever you change this file.
- "version": "7.8",
+ "version": "7.11",
"entries": [
{
"id": 1,
@@ -175,7 +175,11 @@
"id": 11,
"description": "Limit max texure size to 4096 on Macs with Intel GPUs",
"os": {
- "type": "macosx"
+ "type": "macosx",
+ "version": {
+ "op": "<",
+ "value": "10.9"
+ }
},
"vendor_id": "0x8086",
"features": [
@@ -212,7 +216,11 @@
"id": 14,
"description": "Limit max texure size and cube map texture size to 4096 on Macs with AMD GPUs",
"os": {
- "type": "macosx"
+ "type": "macosx",
+ "version": {
+ "op": "<",
+ "value": "10.9"
+ }
},
"vendor_id": "0x1002",
"features": [
@@ -1055,7 +1063,7 @@
"type": "android",
"version": {
"op": "<=",
- "value": "5.0.0"
+ "value": "5.0.1"
}
},
"gl_vendor": "NVIDIA.*",
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc
index 53343f6..eabf9b2 100644
--- a/gpu/config/gpu_info_collector_win.cc
+++ b/gpu/config/gpu_info_collector_win.cc
@@ -665,6 +665,45 @@
return;
}
+ // Track D3D Shader Model (if available)
+ const std::string& shader_version =
+ context_gpu_info.vertex_shader_version;
+
+ // Only gather if this is the first time we're seeing
+ // a non-empty shader version string.
+ if (!shader_version.empty() &&
+ basic_gpu_info->vertex_shader_version.empty()) {
+
+ // Note: do not reorder, used by UMA_HISTOGRAM below
+ enum ShaderModel {
+ SHADER_MODEL_UNKNOWN,
+ SHADER_MODEL_2_0,
+ SHADER_MODEL_3_0,
+ SHADER_MODEL_4_0,
+ SHADER_MODEL_4_1,
+ SHADER_MODEL_5_0,
+ NUM_SHADER_MODELS
+ };
+
+ ShaderModel shader_model = SHADER_MODEL_UNKNOWN;
+
+ if (shader_version == "5.0") {
+ shader_model = SHADER_MODEL_5_0;
+ } else if (shader_version == "4.1") {
+ shader_model = SHADER_MODEL_4_1;
+ } else if (shader_version == "4.0") {
+ shader_model = SHADER_MODEL_4_0;
+ } else if (shader_version == "3.0") {
+ shader_model = SHADER_MODEL_3_0;
+ } else if (shader_version == "2.0") {
+ shader_model = SHADER_MODEL_2_0;
+ }
+
+ UMA_HISTOGRAM_ENUMERATION("GPU.D3DShaderModel",
+ shader_model,
+ NUM_SHADER_MODELS);
+ }
+
MergeGPUInfoGL(basic_gpu_info, context_gpu_info);
basic_gpu_info->dx_diagnostics = context_gpu_info.dx_diagnostics;
diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc
index 11e8e81..b9f5e3a 100644
--- a/gpu/config/software_rendering_list_json.cc
+++ b/gpu/config/software_rendering_list_json.cc
@@ -18,7 +18,7 @@
{
"name": "software rendering list",
// Please update the version number whenever you change this file.
- "version": "9.12",
+ "version": "9.13",
"entries": [
{
"id": 1,
@@ -1165,6 +1165,23 @@
"features": [
"all"
]
+ },
+ {
+ "id": 104,
+ "description": "GPU raster broken on PowerVR Rogue",
+ "cr_bugs": [436331],
+ "os": {
+ "type": "android",
+ "version": {
+ "op": "<",
+ "value": "5.0"
+ }
+ },
+ "gl_renderer": "PowerVR Rogue.*",
+ "features": [
+ "accelerated_2d_canvas",
+ "gpu_rasterization"
+ ]
}
]
}
diff --git a/media/blink/buffered_data_source.cc b/media/blink/buffered_data_source.cc
index 16128f1..55d94d3 100644
--- a/media/blink/buffered_data_source.cc
+++ b/media/blink/buffered_data_source.cc
@@ -20,9 +20,12 @@
// of FFmpeg.
const int kInitialReadBufferSize = 32768;
-// Number of cache misses we allow for a single Read() before signaling an
-// error.
-const int kNumCacheMissRetries = 3;
+// Number of cache misses or read failures we allow for a single Read() before
+// signaling an error.
+const int kLoaderRetries = 3;
+
+// The number of milliseconds to wait before retrying a failed load.
+const int kLoaderFailedRetryDelayMs = 250;
} // namespace
@@ -424,8 +427,19 @@
// Stop the resource load if it failed.
loader_->Stop();
- if (status == BufferedResourceLoader::kCacheMiss &&
- read_op_->retries() < kNumCacheMissRetries) {
+ if (read_op_->retries() < kLoaderRetries) {
+ // Allow some resiliency against sporadic network failures or intentional
+ // cancellations due to a system suspend / resume. Here we treat failed
+ // reads as a cache miss so long as we haven't exceeded max retries.
+ if (status == BufferedResourceLoader::kFailed) {
+ render_task_runner_->PostDelayedTask(
+ FROM_HERE, base::Bind(&BufferedDataSource::ReadCallback,
+ weak_factory_.GetWeakPtr(),
+ BufferedResourceLoader::kCacheMiss, 0),
+ base::TimeDelta::FromMilliseconds(kLoaderFailedRetryDelayMs));
+ return;
+ }
+
read_op_->IncrementRetries();
// Recreate a loader starting from where we last left off until the
diff --git a/media/blink/buffered_data_source_unittest.cc b/media/blink/buffered_data_source_unittest.cc
index a76beb0..688a7a0 100644
--- a/media/blink/buffered_data_source_unittest.cc
+++ b/media/blink/buffered_data_source_unittest.cc
@@ -4,6 +4,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
#include "media/base/media_log.h"
#include "media/base/mock_filters.h"
#include "media/base/test_helpers.h"
@@ -17,7 +18,9 @@
using ::testing::_;
using ::testing::Assign;
+using ::testing::DoAll;
using ::testing::Invoke;
+using ::testing::InvokeWithoutArgs;
using ::testing::InSequence;
using ::testing::NiceMock;
using ::testing::StrictMock;
@@ -410,6 +413,34 @@
Stop();
}
+TEST_F(BufferedDataSourceTest, Http_RetryOnError) {
+ InitializeWith206Response();
+
+ // Read to advance our position.
+ EXPECT_CALL(*this, ReadCallback(kDataSize));
+ EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize - 1));
+ ReadAt(0);
+ ReceiveData(kDataSize);
+
+ // Issue a pending read but trigger an error to force a retry.
+ EXPECT_CALL(*this, ReadCallback(kDataSize));
+ EXPECT_CALL(host_, AddBufferedByteRange(kDataSize, (kDataSize * 2) - 1));
+ ReadAt(kDataSize);
+ base::RunLoop run_loop;
+ EXPECT_CALL(*data_source_, CreateResourceLoader(_, _))
+ .WillOnce(
+ DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit),
+ Invoke(data_source_.get(),
+ &MockBufferedDataSource::CreateMockResourceLoader)));
+ loader()->didFail(url_loader(), response_generator_->GenerateError());
+ run_loop.Run();
+ Respond(response_generator_->Generate206(kDataSize));
+ ReceiveData(kDataSize);
+ FinishLoading();
+ EXPECT_FALSE(data_source_->loading());
+ Stop();
+}
+
TEST_F(BufferedDataSourceTest, File_Retry) {
InitializeWithFileResponse();
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index 65ecd11..015f6b3 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -204,12 +204,16 @@
if (g_forced_alternate_protocol)
return true;
AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server);
- if (it != alternate_protocol_map_.end() &&
- it->second.probability >= alternate_protocol_probability_threshold_) {
- return true;
+ if (it != alternate_protocol_map_.end())
+ return it->second.probability >= alternate_protocol_probability_threshold_;
+
+ auto canonical = GetCanonicalHost(server);
+ if (canonical == canonical_host_to_origin_map_.end() ||
+ canonical->second.Equals(server)) {
+ return false;
}
- return GetCanonicalHost(server) != canonical_host_to_origin_map_.end();
+ return HasAlternateProtocol(canonical->second);
}
std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc
index 1c016b7..2ef6b12 100644
--- a/net/http/http_server_properties_impl_unittest.cc
+++ b/net/http/http_server_properties_impl_unittest.cc
@@ -445,6 +445,36 @@
EXPECT_EQ(".c.youtube.com", impl_.GetCanonicalSuffix(canonical_port_pair));
}
+TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBelowThreshold) {
+ impl_.SetAlternateProtocolProbabilityThreshold(0.02);
+
+ HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
+ HostPortPair canonical_port_pair("bar.c.youtube.com", 80);
+ AlternateProtocolInfo canonical_protocol(1234, QUIC, 0.01);
+
+ impl_.SetAlternateProtocol(canonical_port_pair,
+ canonical_protocol.port,
+ canonical_protocol.protocol,
+ canonical_protocol.probability);
+ EXPECT_FALSE(impl_.HasAlternateProtocol(canonical_port_pair));
+ EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair));
+}
+
+TEST_F(AlternateProtocolServerPropertiesTest, CanonicalAboveThreshold) {
+ impl_.SetAlternateProtocolProbabilityThreshold(0.02);
+
+ HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
+ HostPortPair canonical_port_pair("bar.c.youtube.com", 80);
+ AlternateProtocolInfo canonical_protocol(1234, QUIC, 0.03);
+
+ impl_.SetAlternateProtocol(canonical_port_pair,
+ canonical_protocol.port,
+ canonical_protocol.protocol,
+ canonical_protocol.probability);
+ EXPECT_TRUE(impl_.HasAlternateProtocol(canonical_port_pair));
+ EXPECT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair));
+}
+
TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) {
HostPortPair test_host_port_pair("foo.c.youtube.com", 80);
HostPortPair canonical_port_pair("bar.c.youtube.com", 80);
diff --git a/net/quic/quic_client_session.cc b/net/quic/quic_client_session.cc
index 73a5aec..c8d3195 100644
--- a/net/quic/quic_client_session.cc
+++ b/net/quic/quic_client_session.cc
@@ -718,6 +718,7 @@
read_buffer_->size(),
base::Bind(&QuicClientSession::OnReadComplete,
weak_factory_.GetWeakPtr()));
+ UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.AsyncRead", rv == ERR_IO_PENDING);
if (rv == ERR_IO_PENDING) {
num_packets_read_ = 0;
return;
diff --git a/net/quic/quic_default_packet_writer.cc b/net/quic/quic_default_packet_writer.cc
index d851dfb..177d292 100644
--- a/net/quic/quic_default_packet_writer.cc
+++ b/net/quic/quic_default_packet_writer.cc
@@ -6,6 +6,7 @@
#include "base/location.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
#include "base/metrics/sparse_histogram.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
@@ -24,12 +25,14 @@
QuicDefaultPacketWriter::~QuicDefaultPacketWriter() {}
WriteResult QuicDefaultPacketWriter::WritePacket(
- const char* buffer, size_t buf_len,
+ const char* buffer,
+ size_t buf_len,
const net::IPAddressNumber& self_address,
const net::IPEndPoint& peer_address) {
scoped_refptr<StringIOBuffer> buf(
new StringIOBuffer(std::string(buffer, buf_len)));
DCHECK(!IsWriteBlocked());
+ base::TimeTicks now = base::TimeTicks::Now();
int rv = socket_->Write(buf.get(),
buf_len,
base::Bind(&QuicDefaultPacketWriter::OnWriteComplete,
@@ -45,6 +48,13 @@
}
}
+ base::TimeDelta delta = base::TimeTicks::Now() - now;
+ if (status == WRITE_STATUS_OK) {
+ UMA_HISTOGRAM_TIMES("Net.QuicSession.PacketWriteTime.Synchronous", delta);
+ } else if (status == WRITE_STATUS_BLOCKED) {
+ UMA_HISTOGRAM_TIMES("Net.QuicSession.PacketWriteTime.Asynchronous", delta);
+ }
+
return WriteResult(status, rv);
}
diff --git a/sync/engine/syncer_unittest.cc b/sync/engine/syncer_unittest.cc
index 46fa871..8d97d33 100644
--- a/sync/engine/syncer_unittest.cc
+++ b/sync/engine/syncer_unittest.cc
@@ -4448,6 +4448,217 @@
}
}
+// Tests specifically related to bookmark (and therefore no client tags) sync
+// logic. Entities without client tags have custom logic in parts of the code,
+// and hence are not covered by e.g. the Undeletion tests below.
+class SyncerBookmarksTest : public SyncerTest {
+ public:
+ SyncerBookmarksTest() : metahandle_(syncable::kInvalidMetaHandle) {
+ }
+
+ void Create() {
+ WriteTransaction trans(FROM_HERE, UNITTEST, directory());
+ MutableEntry bookmark(
+ &trans, CREATE, BOOKMARKS, ids_.root(), "clientname");
+ ASSERT_TRUE(bookmark.good());
+ bookmark.PutIsUnsynced(true);
+ bookmark.PutSyncing(false);
+ bookmark.PutSpecifics(DefaultBookmarkSpecifics());
+ EXPECT_FALSE(bookmark.GetIsUnappliedUpdate());
+ EXPECT_FALSE(bookmark.GetId().ServerKnows());
+ metahandle_ = bookmark.GetMetahandle();
+ local_id_ = bookmark.GetId();
+ }
+
+ void Delete() {
+ WriteTransaction trans(FROM_HERE, UNITTEST, directory());
+ MutableEntry entry(&trans, GET_BY_HANDLE, metahandle_);
+ ASSERT_TRUE(entry.good());
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ // The order of setting IS_UNSYNCED vs IS_DEL matters. See
+ // WriteNode::Tombstone().
+ entry.PutIsUnsynced(true);
+ entry.PutIsDel(true);
+ entry.PutSyncing(false);
+ }
+
+ void Undelete() {
+ WriteTransaction trans(FROM_HERE, UNITTEST, directory());
+ MutableEntry entry(&trans, GET_BY_HANDLE, metahandle_);
+ ASSERT_TRUE(entry.good());
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_TRUE(entry.GetIsDel());
+ entry.PutIsDel(false);
+ entry.PutIsUnsynced(true);
+ entry.PutSyncing(false);
+ }
+
+ int64 GetMetahandleOfTag() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+ EXPECT_TRUE(entry.good());
+ if (!entry.good()) {
+ return syncable::kInvalidMetaHandle;
+ }
+ return entry.GetMetahandle();
+ }
+
+ Id GetServerId() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+ EXPECT_TRUE(entry.good());
+ if (!entry.good()) {
+ return Id();
+ }
+ return entry.GetId();
+ }
+
+ void ExpectUnsyncedCreation() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_FALSE(entry.GetIsDel());
+ EXPECT_FALSE(entry.GetServerIsDel()); // Never been committed.
+ EXPECT_LT(entry.GetBaseVersion(), 0);
+ EXPECT_TRUE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ }
+
+ void ExpectUnsyncedUndeletion() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_FALSE(entry.GetIsDel());
+ EXPECT_TRUE(entry.GetServerIsDel());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_TRUE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ EXPECT_TRUE(entry.GetId().ServerKnows());
+ }
+
+ void ExpectUnsyncedEdit() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_FALSE(entry.GetIsDel());
+ EXPECT_FALSE(entry.GetServerIsDel());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_TRUE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ EXPECT_TRUE(entry.GetId().ServerKnows());
+ }
+
+ void ExpectUnsyncedDeletion() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_TRUE(entry.GetIsDel());
+ EXPECT_FALSE(entry.GetServerIsDel());
+ EXPECT_TRUE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_GE(entry.GetServerVersion(), 0);
+ }
+
+ void ExpectSyncedAndCreated() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_FALSE(entry.GetIsDel());
+ EXPECT_FALSE(entry.GetServerIsDel());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_EQ(entry.GetBaseVersion(), entry.GetServerVersion());
+ EXPECT_FALSE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ }
+
+ void ExpectSyncedAndDeleted() {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_TRUE(entry.GetIsDel());
+ EXPECT_TRUE(entry.GetServerIsDel());
+ EXPECT_FALSE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_GE(entry.GetServerVersion(), 0);
+ }
+
+ protected:
+ syncable::Id local_id_;
+ int64 metahandle_;
+};
+
+TEST_F(SyncerBookmarksTest, CreateSyncThenDeleteSync) {
+ Create();
+ ExpectUnsyncedCreation();
+ SyncShareNudge();
+ ExpectSyncedAndCreated();
+ Delete();
+ ExpectUnsyncedDeletion();
+ SyncShareNudge();
+ ExpectSyncedAndDeleted();
+}
+
+TEST_F(SyncerBookmarksTest, CreateThenDeleteBeforeSync) {
+ Create();
+ ExpectUnsyncedCreation();
+ Delete();
+
+ // Deleting before the initial commit should result in not needing to send
+ // the delete to the server. It will still be in an unsynced state, but with
+ // IS_UNSYNCED set to false.
+ {
+ syncable::ReadTransaction trans(FROM_HERE, directory());
+ Entry entry(&trans, GET_BY_HANDLE, metahandle_);
+
+ EXPECT_EQ(metahandle_, entry.GetMetahandle());
+ EXPECT_TRUE(entry.GetIsDel());
+ EXPECT_FALSE(entry.GetServerIsDel());
+ EXPECT_FALSE(entry.GetIsUnsynced());
+ EXPECT_FALSE(entry.GetIsUnappliedUpdate());
+ EXPECT_EQ(entry.GetBaseVersion(), -1);
+ EXPECT_EQ(entry.GetServerVersion(), 0);
+ }
+}
+
+TEST_F(SyncerBookmarksTest, LocalDeleteRemoteChangeConflict) {
+ Create();
+ ExpectUnsyncedCreation();
+ SyncShareNudge();
+ ExpectSyncedAndCreated();
+ Delete();
+ ExpectUnsyncedDeletion();
+
+ // Trigger a getupdates that modifies the bookmark. The update should be
+ // clobbered by the local delete.
+ mock_server_->AddUpdateBookmark(GetServerId(), Id(), "dummy", 10, 10,
+ local_cache_guid(), local_id_.GetServerId());
+
+ SyncShareNudge();
+ ExpectSyncedAndDeleted();
+}
+
+TEST_F(SyncerBookmarksTest, CreateThenDeleteDuringCommit) {
+ Create();
+ ExpectUnsyncedCreation();
+
+ // In the middle of the initial creation commit, perform a deletion.
+ // This should trigger performing two consecutive commit cycles, resulting
+ // in the bookmark being both deleted and synced.
+ mock_server_->SetMidCommitCallback(
+ base::Bind(&SyncerBookmarksTest::Delete, base::Unretained(this)));
+
+ SyncShareNudge();
+ ExpectSyncedAndDeleted();
+}
+
// Test what happens if a client deletes, then recreates, an object very
// quickly. It is possible that the deletion gets sent as a commit, and
// the undelete happens during the commit request. The principle here
@@ -4477,12 +4688,12 @@
void Create() {
WriteTransaction trans(FROM_HERE, UNITTEST, directory());
MutableEntry perm_folder(
- &trans, CREATE, BOOKMARKS, ids_.root(), "clientname");
+ &trans, CREATE, PREFERENCES, ids_.root(), "clientname");
ASSERT_TRUE(perm_folder.good());
perm_folder.PutUniqueClientTag(client_tag_);
perm_folder.PutIsUnsynced(true);
perm_folder.PutSyncing(false);
- perm_folder.PutSpecifics(DefaultBookmarkSpecifics());
+ perm_folder.PutSpecifics(DefaultPreferencesSpecifics());
EXPECT_FALSE(perm_folder.GetIsUnappliedUpdate());
EXPECT_FALSE(perm_folder.GetId().ServerKnows());
metahandle_ = perm_folder.GetMetahandle();
@@ -4494,8 +4705,10 @@
MutableEntry entry(&trans, GET_BY_CLIENT_TAG, client_tag_);
ASSERT_TRUE(entry.good());
EXPECT_EQ(metahandle_, entry.GetMetahandle());
- entry.PutIsDel(true);
+ // The order of setting IS_UNSYNCED vs IS_DEL matters. See
+ // WriteNode::Tombstone().
entry.PutIsUnsynced(true);
+ entry.PutIsDel(true);
entry.PutSyncing(false);
}
@@ -4527,7 +4740,7 @@
EXPECT_EQ(metahandle_, entry.GetMetahandle());
EXPECT_FALSE(entry.GetIsDel());
EXPECT_FALSE(entry.GetServerIsDel()); // Never been committed.
- EXPECT_GE(0, entry.GetBaseVersion());
+ EXPECT_LT(entry.GetBaseVersion(), 0);
EXPECT_TRUE(entry.GetIsUnsynced());
EXPECT_FALSE(entry.GetIsUnappliedUpdate());
}
@@ -4539,7 +4752,7 @@
EXPECT_EQ(metahandle_, entry.GetMetahandle());
EXPECT_FALSE(entry.GetIsDel());
EXPECT_TRUE(entry.GetServerIsDel());
- EXPECT_EQ(0, entry.GetBaseVersion());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
EXPECT_TRUE(entry.GetIsUnsynced());
EXPECT_FALSE(entry.GetIsUnappliedUpdate());
EXPECT_TRUE(entry.GetId().ServerKnows());
@@ -4552,7 +4765,7 @@
EXPECT_EQ(metahandle_, entry.GetMetahandle());
EXPECT_FALSE(entry.GetIsDel());
EXPECT_FALSE(entry.GetServerIsDel());
- EXPECT_LT(0, entry.GetBaseVersion());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
EXPECT_TRUE(entry.GetIsUnsynced());
EXPECT_FALSE(entry.GetIsUnappliedUpdate());
EXPECT_TRUE(entry.GetId().ServerKnows());
@@ -4567,8 +4780,8 @@
EXPECT_FALSE(entry.GetServerIsDel());
EXPECT_TRUE(entry.GetIsUnsynced());
EXPECT_FALSE(entry.GetIsUnappliedUpdate());
- EXPECT_LT(0, entry.GetBaseVersion());
- EXPECT_LT(0, entry.GetServerVersion());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_GE(entry.GetServerVersion(), 0);
}
void ExpectSyncedAndCreated() {
@@ -4578,7 +4791,7 @@
EXPECT_EQ(metahandle_, entry.GetMetahandle());
EXPECT_FALSE(entry.GetIsDel());
EXPECT_FALSE(entry.GetServerIsDel());
- EXPECT_LT(0, entry.GetBaseVersion());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
EXPECT_EQ(entry.GetBaseVersion(), entry.GetServerVersion());
EXPECT_FALSE(entry.GetIsUnsynced());
EXPECT_FALSE(entry.GetIsUnappliedUpdate());
@@ -4593,8 +4806,8 @@
EXPECT_TRUE(entry.GetServerIsDel());
EXPECT_FALSE(entry.GetIsUnsynced());
EXPECT_FALSE(entry.GetIsUnappliedUpdate());
- EXPECT_GE(0, entry.GetBaseVersion());
- EXPECT_GE(0, entry.GetServerVersion());
+ EXPECT_GE(entry.GetBaseVersion(), 0);
+ EXPECT_GE(entry.GetServerVersion(), 0);
}
protected:
@@ -4793,7 +5006,7 @@
{
syncable::ReadTransaction trans(FROM_HERE, directory());
Entry entry(&trans, GET_BY_HANDLE, metahandle_);
- mock_server_->AddUpdateTombstone(entry.GetId());
+ mock_server_->AddUpdateTombstone(entry.GetId(), PREFERENCES);
}
SyncShareNudge();
@@ -4835,7 +5048,7 @@
{
syncable::ReadTransaction trans(FROM_HERE, directory());
Entry entry(&trans, GET_BY_HANDLE, metahandle_);
- mock_server_->AddUpdateTombstone(entry.GetId());
+ mock_server_->AddUpdateTombstone(entry.GetId(), PREFERENCES);
}
SyncShareNudge();
@@ -4903,22 +5116,16 @@
{
syncable::ReadTransaction trans(FROM_HERE, directory());
Entry entry(&trans, GET_BY_HANDLE, metahandle_);
- mock_server_->AddUpdateBookmark(
- entry.GetId(),
- entry.GetParentId(),
- "Thadeusz", 100, 1000,
- local_cache_guid(), local_id_.GetServerId());
+ mock_server_->AddUpdatePref(
+ entry.GetId().GetServerId(),
+ entry.GetParentId().GetServerId(),
+ client_tag_, 100, 1000);
}
mock_server_->SetLastUpdateClientTag(client_tag_);
SyncShareNudge();
EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems());
EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
ExpectSyncedAndCreated();
- {
- syncable::ReadTransaction trans(FROM_HERE, directory());
- Entry entry(&trans, GET_BY_HANDLE, metahandle_);
- EXPECT_EQ("Thadeusz", entry.GetNonUniqueName());
- }
}
TEST_F(SyncerUndeletionTest, OtherClientUndeletesImmediately) {
@@ -4958,22 +5165,16 @@
{
syncable::ReadTransaction trans(FROM_HERE, directory());
Entry entry(&trans, GET_BY_HANDLE, metahandle_);
- mock_server_->AddUpdateBookmark(
- entry.GetId(),
- entry.GetParentId(),
- "Thadeusz", 100, 1000,
- local_cache_guid(), local_id_.GetServerId());
+ mock_server_->AddUpdatePref(
+ entry.GetId().GetServerId(),
+ entry.GetParentId().GetServerId(),
+ client_tag_, 100, 1000);
}
mock_server_->SetLastUpdateClientTag(client_tag_);
SyncShareNudge();
EXPECT_EQ(0, session_->status_controller().TotalNumConflictingItems());
EXPECT_EQ(1, mock_server_->GetAndClearNumGetUpdatesRequests());
ExpectSyncedAndCreated();
- {
- syncable::ReadTransaction trans(FROM_HERE, directory());
- Entry entry(&trans, GET_BY_HANDLE, metahandle_);
- EXPECT_EQ("Thadeusz", entry.GetNonUniqueName());
- }
}
enum {
diff --git a/sync/syncable/directory.cc b/sync/syncable/directory.cc
index 5d11b6f..9c59409 100644
--- a/sync/syncable/directory.cc
+++ b/sync/syncable/directory.cc
@@ -1280,14 +1280,11 @@
trans))
return false;
}
- // Server-unknown items that are locally deleted should not be sent up to
- // the server. They must be !IS_UNSYNCED.
- if (!SyncAssert(!(!id.ServerKnows() && e.GetIsDel() && e.GetIsUnsynced()),
- FROM_HERE,
- "Locally deleted item must not be unsynced.",
- trans)) {
- return false;
- }
+
+ // Previously we would assert that locally deleted items that have never
+ // been synced must not be sent to the server (IS_UNSYNCED must be false).
+ // This is not always true in the case that an item is deleted while the
+ // initial commit is in flight. See crbug.com/426865.
}
return true;
}
diff --git a/sync/syncable/mutable_entry.cc b/sync/syncable/mutable_entry.cc
index b1c1ff4..0aa37e7 100644
--- a/sync/syncable/mutable_entry.cc
+++ b/sync/syncable/mutable_entry.cc
@@ -170,7 +170,9 @@
// - Let us delete this entry permanently through
// DirectoryBackingStore::DropDeletedEntries() when we next restart sync.
// This will save memory and avoid crbug.com/125381.
- if (!GetId().ServerKnows()) {
+ // Note: do not unset IsUnsynced if the syncer is in the middle of
+ // attempting to commit this entity.
+ if (!GetId().ServerKnows() && !GetSyncing()) {
PutIsUnsynced(false);
}
}
diff --git a/sync/test/engine/mock_connection_manager.cc b/sync/test/engine/mock_connection_manager.cc
index ef3022e..4e42f54 100644
--- a/sync/test/engine/mock_connection_manager.cc
+++ b/sync/test/engine/mock_connection_manager.cc
@@ -394,8 +394,9 @@
last_commit_response().entryresponse(0).response_type());
if (last_sent_commit().entries(0).deleted()) {
+ ModelType type = GetModelType(last_sent_commit().entries(0));
AddUpdateTombstone(syncable::Id::CreateFromServerId(
- last_sent_commit().entries(0).id_string()));
+ last_sent_commit().entries(0).id_string()), type);
} else {
sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
ent->CopyFrom(last_sent_commit().entries(0));
@@ -425,7 +426,9 @@
return GetMutableLastUpdate();
}
-void MockConnectionManager::AddUpdateTombstone(const syncable::Id& id) {
+void MockConnectionManager::AddUpdateTombstone(
+ const syncable::Id& id,
+ ModelType type) {
// Tombstones have only the ID set and dummy values for the required fields.
sync_pb::SyncEntity* ent = GetUpdateResponse()->add_entries();
ent->set_id_string(id.GetServerId());
@@ -434,14 +437,15 @@
ent->set_deleted(true);
// Make sure we can still extract the ModelType from this tombstone.
- ent->mutable_specifics()->mutable_bookmark();
+ AddDefaultFieldValue(type, ent->mutable_specifics());
}
void MockConnectionManager::SetLastUpdateDeleted() {
// Tombstones have only the ID set. Wipe anything else.
string id_string = GetMutableLastUpdate()->id_string();
+ ModelType type = GetModelType(*GetMutableLastUpdate());
GetUpdateResponse()->mutable_entries()->RemoveLast();
- AddUpdateTombstone(syncable::Id::CreateFromServerId(id_string));
+ AddUpdateTombstone(syncable::Id::CreateFromServerId(id_string), type);
}
void MockConnectionManager::SetLastUpdateOriginatorFields(
diff --git a/sync/test/engine/mock_connection_manager.h b/sync/test/engine/mock_connection_manager.h
index 19e483b..611d949 100644
--- a/sync/test/engine/mock_connection_manager.h
+++ b/sync/test/engine/mock_connection_manager.h
@@ -145,7 +145,7 @@
// Add a deleted item. Deletion records typically contain no
// additional information beyond the deletion, and no specifics.
// The server may send the originator fields.
- void AddUpdateTombstone(const syncable::Id& id);
+ void AddUpdateTombstone(const syncable::Id& id, ModelType type);
void SetLastUpdateDeleted();
void SetLastUpdateServerTag(const std::string& tag);
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 113c961..d31d2cc 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -9775,6 +9775,14 @@
</summary>
</histogram>
+<histogram name="GPU.D3DShaderModel" enum="ShaderModel">
+ <owner>jmadill@chromium.org</owner>
+ <summary>
+ ANGLE's currently active D3D shader model version. Logged once every startup
+ of the GPU process, on Windows only.
+ </summary>
+</histogram>
+
<histogram name="GPU.InitializeOneOffTime" units="microseconds">
<owner>vangelis@chromium.org</owner>
<summary>
@@ -17518,6 +17526,14 @@
</summary>
</histogram>
+<histogram name="Net.QuicSession.AsyncRead">
+ <owner>rch@chromium.org</owner>
+ <summary>
+ True if the result of reading a packet from the network was ERR_IO_PENDING.
+ Recorded for each packet when Read() returns.
+ </summary>
+</histogram>
+
<histogram name="Net.QuicSession.BlockedFrames.Received">
<owner>rtenneti@chromium.org</owner>
<summary>
@@ -17817,6 +17833,15 @@
</summary>
</histogram>
+<histogram name="Net.QuicSession.PacketWriteTime">
+ <owner>rch@chromium.org</owner>
+ <summary>
+ The time taken to Write() a QUIC packet to the socket. Recorded for each
+ packet when it is sent. The suffix specifies if the write completed
+ synchonously or asynchronously.
+ </summary>
+</histogram>
+
<histogram name="Net.QuicSession.PublicResetAddressMismatch"
enum="QuicAddressMismatch">
<owner>wtc@chromium.org</owner>
@@ -29919,6 +29944,8 @@
<summary>
Records a histogram of the reason why downloads are marked as being
malicious or clean by the improved SafeBrowsing binary download protection.
+ Note that UNSUPPORTED_URL_SCHEME was split out of the INVALID_URL bucket in
+ M41.
</summary>
</histogram>
@@ -40406,6 +40433,12 @@
</summary>
</histogram>
+<histogram name="WrenchMenu.MenuAction" enum="WretchMenuAction">
+ <owner>ainslie@chromium.org</owner>
+ <owner>edwardjung@chromium.org</owner>
+ <summary>Number of times that each menu item is clicked.</summary>
+</histogram>
+
<histogram name="WrenchMenu.RecentTabsSubMenu" enum="RecentTabsAction">
<owner>rpop@chromium.org</owner>
<summary>
@@ -40414,6 +40447,14 @@
</summary>
</histogram>
+<histogram name="WrenchMenu.TimeToAction">
+ <owner>ainslie@chromium.org</owner>
+ <owner>edwardjung@chromium.org</owner>
+ <summary>
+ The time a user takes to select a menu itme after opening the menu.
+ </summary>
+</histogram>
+
<histogram name="ZeroSuggest.AllResults">
<owner>hfung@chromium.org</owner>
<summary>
@@ -47927,6 +47968,7 @@
<int value="-1662447331" label="wake-on-packets"/>
<int value="-1654344175" label="disable-extension-info-dialog"/>
<int value="-1619757314" label="touch-scrolling-mode"/>
+ <int value="-1614912400" label="enable-link-disambiguation-popup"/>
<int value="-1605567628" label="disable-overlay-scrollbar"/>
<int value="-1596559650" label="max-tiles-for-interest-area"/>
<int value="-1571841513" label="enable-devtools-experiments"/>
@@ -48091,6 +48133,7 @@
<int value="880510010" label="enable-permissions-bubbles"/>
<int value="887011602" label="enable-spelling-auto-correct"/>
<int value="909439558" label="disable-device-discovery"/>
+ <int value="929462705" label="disable-link-disambiguation-popup"/>
<int value="952558794" label="enable-remote-assistance"/>
<int value="980396200" label="enable-new-korean-ime"/>
<int value="1022992701" label="enable-origin-chip-always"/>
@@ -53127,6 +53170,7 @@
<int value="19" label="ARCHIVE_WITHOUT_BINARIES"/>
<int value="20" label="DOWNLOAD_DANGEROUS_HOST"/>
<int value="21" label="DOWNLOAD_POTENTIALLY_UNWANTED"/>
+ <int value="22" label="UNSUPPORTED_URL_SCHEME"/>
</enum>
<enum name="SBClientDownloadExtensions" type="int">
@@ -53472,6 +53516,16 @@
<int value="4" label="Expires before Jan 1, 2016"/>
</enum>
+<enum name="ShaderModel" type="int">
+ <summary>The GPU's Direct3D shader model version.</summary>
+ <int value="0" label="SHADER_MODEL_UNKNOWN"/>
+ <int value="1" label="SHADER_MODEL_2_0"/>
+ <int value="2" label="SHADER_MODEL_3_0"/>
+ <int value="3" label="SHADER_MODEL_4_0"/>
+ <int value="4" label="SHADER_MODEL_4_1"/>
+ <int value="5" label="SHADER_MODEL_5_0"/>
+</enum>
+
<enum name="ShelfAlignmentValue" type="int">
<summary>
The alignment of the shelf area (see ash/launcher/launcher_view.cc).
@@ -55972,6 +56026,53 @@
<int value="3" label="Packaged App"/>
</enum>
+<enum name="WretchMenuAction" type="int">
+ <int value="0" label="New tab"/>
+ <int value="1" label="New window"/>
+ <int value="2" label="New incognito window"/>
+ <int value="3" label="Show bookmark bar"/>
+ <int value="4" label="Show bookmark manager"/>
+ <int value="5" label="Import settings"/>
+ <int value="6" label="Bookmark page"/>
+ <int value="7" label="Bookmark all tabs"/>
+ <int value="8" label="Pin to start screen"/>
+ <int value="9" label="Restore tab"/>
+ <int value="10" label="Win desktop restart"/>
+ <int value="11" label="Win8 metro restart"/>
+ <int value="12" label="Win chromeos restart"/>
+ <int value="13" label="Distill page"/>
+ <int value="14" label="Save page"/>
+ <int value="15" label="Find"/>
+ <int value="16" label="Print"/>
+ <int value="17" label="Cut"/>
+ <int value="18" label="Copy"/>
+ <int value="19" label="Paste"/>
+ <int value="20" label="Create hosted app"/>
+ <int value="21" label="Create shortcuts"/>
+ <int value="22" label="Manage extensions"/>
+ <int value="23" label="Task manager"/>
+ <int value="24" label="Clear browsing data"/>
+ <int value="25" label="View source"/>
+ <int value="26" label="Dev tools"/>
+ <int value="27" label="Dev tools console"/>
+ <int value="28" label="Dev tools devices"/>
+ <int value="29" label="Profiling enabled"/>
+ <int value="30" label="Zoom minus"/>
+ <int value="31" label="Zoom plus"/>
+ <int value="32" label="Fullscreen"/>
+ <int value="33" label="Show history"/>
+ <int value="34" label="Show downloads"/>
+ <int value="35" label="Show sync setup"/>
+ <int value="36" label="Options"/>
+ <int value="37" label="About"/>
+ <int value="38" label="Help page via menu"/>
+ <int value="39" label="Feedback"/>
+ <int value="40" label="Toggle request tablet site"/>
+ <int value="41" label="Recent tab"/>
+ <int value="42" label="Open a bookmark"/>
+ <int value="43" label="Exit"/>
+</enum>
+
<enum name="XMLHttpRequestSendArrayBufferOrView" type="int">
<int value="0" label="XMLHttpRequestSendArrayBuffer"/>
<int value="1" label="XMLHttpRequestSendArrayBufferView"/>
@@ -57044,6 +57145,12 @@
<affected-histogram name="Net.TCP_Connection_Latency_Interval"/>
</histogram_suffixes>
+<histogram_suffixes name="IOMode" separator=".">
+ <suffix name="Synchronous"/>
+ <suffix name="Asynchronous"/>
+ <affected-histogram name="Net.QuicSession.PacketWriteTime"/>
+</histogram_suffixes>
+
<histogram_suffixes name="IPProtocolType" separator="_">
<suffix name="UDP"/>
<suffix name="TCP"/>
@@ -59729,6 +59836,52 @@
<affected-histogram name="NewTabPage.DefaultPageType"/>
</histogram_suffixes>
+<histogram_suffixes name="WrenchMenuActionTimings" separator=".">
+ <suffix name="NewTab"/>
+ <suffix name="NewWindow"/>
+ <suffix name="NewIncognitoWindow"/>
+ <suffix name="ShowBookmarkBar"/>
+ <suffix name="ShowBookmarkMgr"/>
+ <suffix name="ImportSettings"/>
+ <suffix name="BookmarkPage"/>
+ <suffix name="BookmarkAllTabs"/>
+ <suffix name="PinToStartScreen"/>
+ <suffix name="RestoreTab"/>
+ <suffix name="WinDesktopRestart"/>
+ <suffix name="Win8MetroRestart"/>
+ <suffix name="ChromeOSRestart"/>
+ <suffix name="DistillPage"/>
+ <suffix name="SavePage"/>
+ <suffix name="Find"/>
+ <suffix name="Print"/>
+ <suffix name="Cut"/>
+ <suffix name="Copy"/>
+ <suffix name="Paste"/>
+ <suffix name="CreateHostedApp"/>
+ <suffix name="CreateShortcuts"/>
+ <suffix name="ManageExtensions"/>
+ <suffix name="TaskManager"/>
+ <suffix name="ClearBrowsingData"/>
+ <suffix name="ViewSource"/>
+ <suffix name="DevTools"/>
+ <suffix name="DevToolsConsole"/>
+ <suffix name="DevToolsDevices"/>
+ <suffix name="ProfilingEnabled"/>
+ <suffix name="ZoomMinus"/>
+ <suffix name="ZoomPlus"/>
+ <suffix name="EnterFullScreen"/>
+ <suffix name="ShowHistory"/>
+ <suffix name="ShowDownloads"/>
+ <suffix name="ShowSyncSetup"/>
+ <suffix name="Settings"/>
+ <suffix name="About"/>
+ <suffix name="HelpPage"/>
+ <suffix name="Feedback"/>
+ <suffix name="RequestTabletSite"/>
+ <suffix name="Exit"/>
+ <affected-histogram name="WrenchMenu.TimeToAction"/>
+</histogram_suffixes>
+
</histogram_suffixes_list>
</histogram-configuration>
diff --git a/ui/base/ui_base_switches.cc b/ui/base/ui_base_switches.cc
index 2163397..24d0d55 100644
--- a/ui/base/ui_base_switches.cc
+++ b/ui/base/ui_base_switches.cc
@@ -27,6 +27,10 @@
// Disables controls that support touch base text editing.
const char kDisableTouchEditing[] = "disable-touch-editing";
+// Enables a zoomed popup bubble that allows the user to select a link.
+const char kEnableLinkDisambiguationPopup[] =
+ "enable-link-disambiguation-popup";
+
// Enables an experimental focus manager to track text input clients.
const char kEnableTextInputFocusManager[] = "enable-text-input-focus-manager";
diff --git a/ui/base/ui_base_switches.h b/ui/base/ui_base_switches.h
index 629f9af..b4d503b 100644
--- a/ui/base/ui_base_switches.h
+++ b/ui/base/ui_base_switches.h
@@ -21,6 +21,7 @@
UI_BASE_EXPORT extern const char kDisableTouchAdjustment[];
UI_BASE_EXPORT extern const char kDisableTouchDragDrop[];
UI_BASE_EXPORT extern const char kDisableTouchEditing[];
+UI_BASE_EXPORT extern const char kEnableLinkDisambiguationPopup[];
UI_BASE_EXPORT extern const char kEnableTextInputFocusManager[];
UI_BASE_EXPORT extern const char kEnableTouchDragDrop[];
UI_BASE_EXPORT extern const char kEnableTouchEditing[];
diff --git a/ui/base/ui_base_switches_util.cc b/ui/base/ui_base_switches_util.cc
index 58b85c7..7a89264 100644
--- a/ui/base/ui_base_switches_util.cc
+++ b/ui/base/ui_base_switches_util.cc
@@ -9,6 +9,18 @@
namespace switches {
+bool IsLinkDisambiguationPopupEnabled() {
+#if defined(OS_ANDROID)
+ return true;
+#else
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableLinkDisambiguationPopup)) {
+ return true;
+ }
+ return false;
+#endif
+}
+
bool IsTextInputFocusManagerEnabled() {
return CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableTextInputFocusManager);
diff --git a/ui/base/ui_base_switches_util.h b/ui/base/ui_base_switches_util.h
index de08d1c..213aed6 100644
--- a/ui/base/ui_base_switches_util.h
+++ b/ui/base/ui_base_switches_util.h
@@ -9,6 +9,7 @@
namespace switches {
+UI_BASE_EXPORT bool IsLinkDisambiguationPopupEnabled();
UI_BASE_EXPORT bool IsTextInputFocusManagerEnabled();
UI_BASE_EXPORT bool IsTouchDragDropEnabled();
UI_BASE_EXPORT bool IsTouchEditingEnabled();
diff --git a/ui/events/latency_info.cc b/ui/events/latency_info.cc
index 4aadd66..1f88669 100644
--- a/ui/events/latency_info.cc
+++ b/ui/events/latency_info.cc
@@ -29,9 +29,6 @@
CASE_TYPE(INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT);
CASE_TYPE(WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT);
CASE_TYPE(WINDOW_OLD_SNAPSHOT_FRAME_NUMBER_COMPONENT);
- CASE_TYPE(INPUT_EVENT_BROWSER_COMPOSITE_COMPONENT);
- CASE_TYPE(INPUT_EVENT_BROWSER_SWAP_BUFFER_COMPONENT);
- CASE_TYPE(INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT);
CASE_TYPE(INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT);
diff --git a/ui/events/latency_info.h b/ui/events/latency_info.h
index 00343af..454e561 100644
--- a/ui/events/latency_info.h
+++ b/ui/events/latency_info.h
@@ -54,13 +54,6 @@
WINDOW_OLD_SNAPSHOT_FRAME_NUMBER_COMPONENT,
// Timestamp when a tab is requested to be shown.
TAB_SHOW_COMPONENT,
- // Timestamp of when the Browser process began compositing
- INPUT_EVENT_BROWSER_COMPOSITE_COMPONENT,
- // Timestamp of when the Browser process began swap buffers
- INPUT_EVENT_BROWSER_SWAP_BUFFER_COMPONENT,
- // Timestamp of when the gpu service began swap buffers, unlike
- // INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT which measure after
- INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT,
// ---------------------------TERMINAL COMPONENT-----------------------------
// TERMINAL COMPONENT is when we show the latency end in chrome://tracing.
// Timestamp when the mouse event is acked from renderer and it does not
@@ -111,7 +104,7 @@
};
// Empirically determined constant based on a typical scroll sequence.
- enum { kTypicalMaxComponentsPerLatencyInfo = 9 };
+ enum { kTypicalMaxComponentsPerLatencyInfo = 6 };
enum { kMaxInputCoordinates = 2 };
diff --git a/ui/file_manager/gallery/js/image_editor/exif_encoder.js b/ui/file_manager/gallery/js/image_editor/exif_encoder.js
index 80fdef8..5874be3 100644
--- a/ui/file_manager/gallery/js/image_editor/exif_encoder.js
+++ b/ui/file_manager/gallery/js/image_editor/exif_encoder.js
@@ -87,7 +87,7 @@
var pixelCount = this.metadata_.width * this.metadata_.height;
var maxEncodedSize = 5000 * Math.min(10, 1 + pixelCount / 1000000);
- var DATA_URL_PREFIX = 'data:' + this.mimeType + ';base64,';
+ var DATA_URL_PREFIX = 'data:' + this.metadata_.media.mimeType + ';base64,';
var BASE64_BLOAT = 4 / 3;
var maxDataURLLength =
DATA_URL_PREFIX.length + Math.ceil(maxEncodedSize * BASE64_BLOAT);
diff --git a/ui/file_manager/gallery/js/image_editor/image_encoder.js b/ui/file_manager/gallery/js/image_editor/image_encoder.js
index 0cc5e65..78f2049 100644
--- a/ui/file_manager/gallery/js/image_editor/image_encoder.js
+++ b/ui/file_manager/gallery/js/image_editor/image_encoder.js
@@ -31,7 +31,7 @@
*/
ImageEncoder.createMetadataEncoder = function(metadata) {
var constructor =
- (metadata && ImageEncoder.metadataEncoders[metadata.mimeType]) ||
+ (metadata && ImageEncoder.metadataEncoders[metadata.media.mimeType]) ||
ImageEncoder.MetadataEncoder;
return new constructor(metadata);
};
@@ -73,7 +73,7 @@
// WebKit does not support canvas.toBlob yet so canvas.toDataURL is
// the only way to use the Chrome built-in image encoder.
var dataURL =
- canvas.toDataURL(metadataEncoder.getMetadata().mimeType, quality);
+ canvas.toDataURL(metadataEncoder.getMetadata().media.mimeType, quality);
ImageUtil.trace.reportTimer('dataurl');
var encodedImage = ImageEncoder.decodeDataURL(dataURL);
@@ -102,7 +102,8 @@
appendSlice(ImageEncoder.stringToArrayBuffer(
encodedImage, 0, encodedImage.length));
}
- var blob = new Blob(slices, {type: metadataEncoder.getMetadata().mimeType});
+ var blob = new Blob(slices,
+ {type: metadataEncoder.getMetadata().media.mimeType});
ImageUtil.trace.reportTimer('blob');
return blob;
};
@@ -175,10 +176,10 @@
*/
ImageEncoder.MetadataEncoder = function(original_metadata) {
this.metadata_ = MetadataCache.cloneMetadata(original_metadata) || {};
- if (this.metadata_.mimeType != 'image/jpeg') {
+ if (this.metadata_.media.mimeType !== 'image/jpeg') {
// Chrome can only encode JPEG and PNG. Force PNG mime type so that we
// can save to file and generate a thumbnail.
- this.metadata_.mimeType = 'image/png';
+ this.metadata_.media.mimeType = 'image/png';
}
};
@@ -206,7 +207,7 @@
ImageEncoder.MetadataEncoder.prototype.setThumbnailData =
function(canvas, quality) {
this.metadata_.thumbnailURL =
- canvas.toDataURL(this.metadata_.mimeType, quality);
+ canvas.toDataURL(this.metadata_.media.mimeType, quality);
delete this.metadata_.thumbnailTransform;
};
diff --git a/ui/webui/resources/css/widgets.css b/ui/webui/resources/css/widgets.css
index e4c7a59..e4ff82a 100644
--- a/ui/webui/resources/css/widgets.css
+++ b/ui/webui/resources/css/widgets.css
@@ -270,6 +270,7 @@
[is='action-link'][disabled] {
color: #999;
cursor: default;
+ pointer-events: none;
text-decoration: none;
}
diff --git a/ui/webui/resources/js/action_link.js b/ui/webui/resources/js/action_link.js
index 30685b0..5dea966 100644
--- a/ui/webui/resources/js/action_link.js
+++ b/ui/webui/resources/js/action_link.js
@@ -37,13 +37,11 @@
/** @this {ActionLink} */
createdCallback: function() {
- // Links aren't tabble unless there's an [href] attribute set. Setting
- // this adds undesirable "Open link in new tab..." context menu handlers
- // so just manually add to tab order instead.
- this.tabIndex = 0;
+ // Action links can start disabled (e.g. <a is="action-link" disabled>).
+ this.tabIndex = this.disabled ? -1 : 0;
this.addEventListener('keydown', function(e) {
- if (e.keyIdentifier == 'Enter') {
+ if (!this.disabled && e.keyIdentifier == 'Enter') {
// Schedule a click asynchronously because other 'keydown' handlers
// may still run later (e.g. document.addEventListener('keydown')).
// Specifically options dialogs break when this timeout isn't here.
@@ -53,6 +51,34 @@
}
});
},
+
+ /** @type {boolean} */
+ set disabled(disabled) {
+ if (disabled)
+ HTMLAnchorElement.prototype.setAttribute.call(this, 'disabled', '');
+ else
+ HTMLAnchorElement.prototype.removeAttribute.call(this, 'disabled');
+ this.tabIndex = disabled ? -1 : 0;
+ },
+ get disabled() {
+ return this.hasAttribute('disabled');
+ },
+
+ /** @override */
+ setAttribute: function(attr, val) {
+ if (attr.toLowerCase() == 'disabled')
+ this.disabled = true;
+ else
+ HTMLAnchorElement.prototype.setAttribute.apply(this, arguments);
+ },
+
+ /** @override */
+ removeAttribute: function(attr) {
+ if (attr.toLowerCase() == 'disabled')
+ this.disabled = false;
+ else
+ HTMLAnchorElement.prototype.removeAttribute.apply(this, arguments);
+ },
},
extends: 'a',
});