diff --git a/.gn b/.gn index 3a7b224f..70856f6 100644 --- a/.gn +++ b/.gn
@@ -386,6 +386,7 @@ # "//third_party/crashpad/*", 20ish errors "//third_party/crc32c/*", "//third_party/cros_system_api/*", + "//third_party/custom_tabs_client/*", "//third_party/cython/*", "//third_party/d3/*", "//third_party/dawn/*",
diff --git a/DEPS b/DEPS index 01dac9e..c4b4011 100644 --- a/DEPS +++ b/DEPS
@@ -145,7 +145,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '593290ed75fd3fbf060d94021925cdf76c62c38e', + 'skia_revision': 'b2c5a94b1c7a40a223c198573aa9bd83998945e4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -157,7 +157,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '483ee3fa2315298aba6cbaf6f62d515f7214c0f7', + 'angle_revision': '93560ef51dc1e79ddeb2d6dcbb8f33eb83ade1b9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -224,7 +224,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'feed_revision': '4f87f10f5d5a589dbfd10815222d5d37fe267f06', + 'feed_revision': 'f4372718f4cabd57efeab02f5726ed147f29768f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling android_sdk_build-tools_version # and whatever else without interference from each other. @@ -280,11 +280,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '1cd83ffbdd5d5f870f57398768555d3d97068177', + 'dawn_revision': '421584173cae282ee496291b1cb08eebcad71be7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'b71a08181bcb67b75f9b4f44fa92237816ade534', + 'quiche_revision': 'f35ea98e9c0aae429b91fac10a2cc40fff84c938', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -664,11 +664,6 @@ 'dep_type': 'cipd', }, - 'src/third_party/android_sdk/androidx_browser/src': { - 'url': Var('chromium_git') + '/external/gob/android/platform/frameworks/support/browser.git' + '@' + 'aeeea8bd0a6703bc4a148e9bcd6998553def74ab', - 'condition': 'checkout_android', - }, - 'src/third_party/android_sdk/public': { 'packages': [ { @@ -814,7 +809,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '6454258063cd52c8667a82668a537cb52de4a161', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '863bf72e6d5da911279b064e499e3d5d64685e59', 'condition': 'checkout_linux', }, @@ -839,7 +834,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'aa2db565b32b0993a834348932c69424993e3f06', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a110bf60c043d93a23c105215f000b88a2825c49', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1212,7 +1207,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '887948c03303365c7466f047e93e634bd1ca6ae2', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '0a8f3c09ad39006cd3066668e255edd47ea2f80b', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1380,7 +1375,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'abaae129d9a0c6e1e092067e0b105475df43352e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'b6685420c42a6b0903e2d4e9e5a270261d30a52d', + Var('webrtc_git') + '/src.git' + '@' + '3cc2f70bc33c3bfba6732d896e8c25a861d9b8b7', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1421,7 +1416,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@97c6c359d43f7b1c926208166ae4a4029d8b3bd8', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1e32e832b77e6b9fa3137d360cf011096bbd6af8', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index fad37d5..82166d3 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -30,6 +30,12 @@ } } +generate_jni("common_jni_headers") { + sources = [ + "java/src/org/chromium/android_webview/common/AwResource.java", + ] +} + generate_jni("native_jni") { sources = [ "apk/java/src/com/android/webview/chromium/WebViewApkApplication.java", @@ -869,24 +875,25 @@ "java/src/org/chromium/android_webview/permission/AwGeolocationCallback.java", "java/src/org/chromium/android_webview/permission/AwPermissionRequest.java", "java/src/org/chromium/android_webview/policy/AwPolicyProvider.java", + "java/src/org/chromium/android_webview/ui/util/CrashInfoLoader.java", "java/src/org/chromium/android_webview/ui/util/UnuploadedFilesStateLoader.java", "java/src/org/chromium/android_webview/ui/util/UploadedCrashesInfoLoader.java", "java/src/org/chromium/android_webview/ui/util/WebViewCrashLogParser.java", ] deps = [ - ":android_webview_commandline_java", - ":android_webview_crash_info_java", - ":android_webview_platform_services_java", ":android_webview_services_java", - ":android_webview_variations_utils_java", - ":resources", - ":strings_grd", - ":system_webview_manifest", + ":common_commandline_java", + ":common_crash_info_java", # This includes AwResource, which may be called via JNI. We're including it # here because there's currently no good way to enforce that it gets included # when it's depended on via JNI. - "//android_webview/common:common_java", + ":common_java", + ":common_platform_services_java", + ":common_variations_utils_java", + ":resources", + ":strings_grd", + ":system_webview_manifest", "//base:base_java", "//components/autofill/android:autofill_java", "//components/autofill/android:provider_java", @@ -930,8 +937,8 @@ min_sdk_version = 21 } -android_library("android_webview_variations_utils_java") { - java_files = [ "java/src/org/chromium/android_webview/VariationsUtils.java" ] +android_library("common_variations_utils_java") { + java_files = [ "java/src/org/chromium/android_webview/common/variations/VariationsUtils.java" ] deps = [ "//android_webview/proto:aw_variations_seed_proto_java", "//base:base_java", @@ -1019,24 +1026,48 @@ jar_excluded_patterns = [ "*/PlatformServiceBridgeImpl.class" ] } +android_library("common_platform_services_java") { + java_files = [ + "java/src/org/chromium/android_webview/common/PlatformServiceBridge.java", + "java/src/org/chromium/android_webview/common/PlatformServiceBridgeImpl.java", + ] + + deps = [ + "//base:base_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + ] + + # The appropriate .class file will be loaded via a dependency to a library + # like :platform_service_bridge_upstream_implementation_java below. We only include the + # .java file because other files in the target depend on it. + jar_excluded_patterns = [ "*/PlatformServiceBridgeImpl.class" ] +} + # This target compiles the implementation of PlatformServiceBridge for AOSP targets. android_library("platform_service_bridge_upstream_implementation_java") { - java_files = - [ "java/src/org/chromium/android_webview/PlatformServiceBridgeImpl.java" ] + java_files = [ "java/src/org/chromium/android_webview/common/PlatformServiceBridgeImpl.java" ] deps = [ - ":android_webview_platform_services_java", + ":common_platform_services_java", ] } -android_library("android_webview_crash_info_java") { +android_library("common_crash_info_java") { java_files = - [ "java/src/org/chromium/android_webview/ui/util/CrashInfoLoader.java" ] + [ "java/src/org/chromium/android_webview/common/crash/CrashInfo.java" ] deps = [ "//base:base_java", ] } +android_library("common_java") { + java_files = + [ "java/src/org/chromium/android_webview/common/AwResource.java" ] + deps = [ + "//base:base_java", + ] +} + android_library("android_webview_commandline_java") { java_files = [ "java/src/org/chromium/android_webview/command_line/CommandLineUtil.java", @@ -1047,6 +1078,15 @@ ] } +android_library("common_commandline_java") { + java_files = + [ "java/src/org/chromium/android_webview/common/CommandLineUtil.java" ] + + deps = [ + "//base:base_java", + ] +} + # Keep WebView's services separate from other WebView code to keep their deps clean # (and make them easy to move). android_library("android_webview_services_java") { @@ -1059,10 +1099,10 @@ "java/src/org/chromium/android_webview/services/VariationsSeedServer.java", ] deps = [ - ":android_webview_commandline_java", - ":android_webview_crash_info_java", - ":android_webview_platform_services_java", - ":android_webview_variations_utils_java", + ":common_commandline_java", + ":common_crash_info_java", + ":common_platform_services_java", + ":common_variations_utils_java", ":system_webview_manifest", "//android_webview/apk:apk_java", "//base:base_java",
diff --git a/android_webview/apk/BUILD.gn b/android_webview/apk/BUILD.gn index a130678..2daa630 100644 --- a/android_webview/apk/BUILD.gn +++ b/android_webview/apk/BUILD.gn
@@ -31,8 +31,8 @@ "java/src/com/android/webview/chromium/WebViewApkApplication.java", ] deps = [ - "//android_webview:android_webview_commandline_java", "//android_webview:android_webview_locale_config_java", + "//android_webview:common_commandline_java", "//base:base_java", "//components/embedder_support/android:application_java", "//ui/android:ui_java",
diff --git a/android_webview/apk/java/src/com/android/webview/chromium/WebViewApkApplication.java b/android_webview/apk/java/src/com/android/webview/chromium/WebViewApkApplication.java index f6cd74f..da9af528 100644 --- a/android_webview/apk/java/src/com/android/webview/chromium/WebViewApkApplication.java +++ b/android_webview/apk/java/src/com/android/webview/chromium/WebViewApkApplication.java
@@ -8,7 +8,7 @@ import android.content.Context; import org.chromium.android_webview.AwLocaleConfig; -import org.chromium.android_webview.command_line.CommandLineUtil; +import org.chromium.android_webview.common.CommandLineUtil; import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils; import org.chromium.base.annotations.JNINamespace;
diff --git a/android_webview/common/BUILD.gn b/android_webview/common/BUILD.gn index 1619d3c..d44a0772 100644 --- a/android_webview/common/BUILD.gn +++ b/android_webview/common/BUILD.gn
@@ -5,12 +5,6 @@ import("//build/config/android/rules.gni") import("//mojo/public/tools/bindings/mojom.gni") -generate_jni("native_jni") { - sources = [ - "../java/src/org/chromium/android_webview/common/AwResource.java", - ] -} - mojom("common_mojom") { sources = [ "js_java_interaction/interfaces.mojom", @@ -52,7 +46,7 @@ "url_constants.h", ] deps = [ - ":native_jni", + "//android_webview:common_jni_headers", "//base", "//components/cdm/common", "//components/crash/content/app", @@ -73,11 +67,3 @@ "//url", ] } - -android_library("common_java") { - java_files = - [ "../java/src/org/chromium/android_webview/common/AwResource.java" ] - deps = [ - "//base:base_java", - ] -}
diff --git a/android_webview/common/DEPS b/android_webview/common/DEPS index d5b65ca7..686085e 100644 --- a/android_webview/common/DEPS +++ b/android_webview/common/DEPS
@@ -1,7 +1,7 @@ include_rules = [ "-android_webview", "+android_webview/common", - "+android_webview/native_jni", + "+android_webview/common_jni_headers", "+components/cdm/common", "+components/printing/common", "+media/base/android",
diff --git a/android_webview/common/aw_resource.cc b/android_webview/common/aw_resource.cc index 6033ec1..e94fca77 100644 --- a/android_webview/common/aw_resource.cc +++ b/android_webview/common/aw_resource.cc
@@ -4,7 +4,7 @@ #include "android_webview/common/aw_resource.h" -#include "android_webview/common/native_jni/AwResource_jni.h" +#include "android_webview/common_jni_headers/AwResource_jni.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h"
diff --git a/android_webview/docs/commandline-flags.md b/android_webview/docs/commandline-flags.md index a325aac..24039c9 100644 --- a/android_webview/docs/commandline-flags.md +++ b/android_webview/docs/commandline-flags.md
@@ -103,4 +103,4 @@ ## Implementation -See [CommandLineUtil.java](https://cs.chromium.org/chromium/src/android_webview/java/src/org/chromium/android_webview/command_line/CommandLineUtil.java). +See [CommandLineUtil.java](https://cs.chromium.org/chromium/src/android_webview/java/src/org/chromium/android_webview/common/CommandLineUtil.java).
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn index 1b1ad80..d4882c7 100644 --- a/android_webview/glue/BUILD.gn +++ b/android_webview/glue/BUILD.gn
@@ -9,12 +9,11 @@ android_library("glue") { deps = [ - "//android_webview:android_webview_commandline_java", "//android_webview:android_webview_java", "//android_webview:android_webview_locale_config_java", - "//android_webview:android_webview_platform_services_java", + "//android_webview:common_commandline_java", + "//android_webview:common_java", "//android_webview:system_webview_manifest", - "//android_webview/common:common_java", "//android_webview/support_library/boundary_interfaces:boundary_interface_java", "//android_webview/support_library/callback:callback_java", "//base:base_java",
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java index bbeee392..cb2adb7 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -37,7 +37,7 @@ import org.chromium.android_webview.AwSwitches; import org.chromium.android_webview.ResourcesContextWrapperFactory; import org.chromium.android_webview.WebViewChromiumRunQueue; -import org.chromium.android_webview.command_line.CommandLineUtil; +import org.chromium.android_webview.common.CommandLineUtil; import org.chromium.base.BuildInfo; import org.chromium.base.BundleUtils; import org.chromium.base.CommandLine;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java index 50fe5e5..16b430b2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.content.SharedPreferences; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java index f7578aa3..f23e734 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -14,7 +14,8 @@ import android.os.RemoteException; import android.os.StrictMode; -import org.chromium.android_webview.command_line.CommandLineUtil; +import org.chromium.android_webview.common.CommandLineUtil; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.android_webview.policy.AwPolicyProvider; import org.chromium.android_webview.services.CrashReceiverService; import org.chromium.android_webview.services.ICrashReceiverService;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java index 1d56b491b..58fc51c2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.net.Uri; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwMetricsLogUploader.java b/android_webview/java/src/org/chromium/android_webview/AwMetricsLogUploader.java index e5e7690..43122da 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwMetricsLogUploader.java +++ b/android_webview/java/src/org/chromium/android_webview/AwMetricsLogUploader.java
@@ -4,6 +4,7 @@ package org.chromium.android_webview; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java index bb1f9d3..b3ef9d2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSafeBrowsingConfigHelper.java
@@ -10,6 +10,7 @@ import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.base.Callback; import org.chromium.base.CommandLine; import org.chromium.base.Log;
diff --git a/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java b/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java index 904a2604..c84ee42 100644 --- a/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java +++ b/android_webview/java/src/org/chromium/android_webview/VariationsSeedLoader.java
@@ -14,6 +14,7 @@ import android.os.RemoteException; import android.os.SystemClock; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.android_webview.services.IVariationsSeedServer; import org.chromium.android_webview.services.VariationsSeedServer; import org.chromium.base.ContextUtils;
diff --git a/android_webview/java/src/org/chromium/android_webview/common/CommandLineUtil.java b/android_webview/java/src/org/chromium/android_webview/common/CommandLineUtil.java new file mode 100644 index 0000000..4aef44f1 --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/common/CommandLineUtil.java
@@ -0,0 +1,58 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.common; + +import android.os.StrictMode; + +import org.chromium.base.BuildInfo; +import org.chromium.base.CommandLine; + +/** + * Utility class for WebView's CommandLine - this is compiled into a separate target that can be + * reached from WebView's separate minidump-uploading Services. + */ +public class CommandLineUtil { + protected CommandLineUtil() {} + + public static final String WEBVIEW_COMMAND_LINE_FILE = "/data/local/tmp/webview-command-line"; + + // same switch as kEnableCrashReporterForTesting in //base/base_switches.h + public static final String CRASH_UPLOADS_ENABLED_FOR_TESTING_SWITCH = + "enable-crash-reporter-for-testing"; + + private static final String COMMAND_LINE_UTIL_INTERNAL = + "org.chromium.android_webview.command_line.CommandLineUtilInternal"; + + private static CommandLineUtil sInstance; + + private static CommandLineUtil getInstance() { + if (sInstance != null) return sInstance; + try { + sInstance = (CommandLineUtil) Class.forName(COMMAND_LINE_UTIL_INTERNAL).newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException + | IllegalArgumentException e) { + sInstance = new CommandLineUtil(); + } + return sInstance; + } + + /** + * Initialize the CommandLine for WebView - this should be initialized on the same thread where + * we subsequently access CommandLine. + */ + public static void initCommandLine() { + if (BuildInfo.isDebugAndroid()) { + // Suppress the StrictMode violation as this codepath is only hit on debuggable builds. + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + CommandLine.initFromFile(CommandLineUtil.WEBVIEW_COMMAND_LINE_FILE); + StrictMode.setThreadPolicy(oldPolicy); + } else { + CommandLine.init(null); + } + getInstance().initCommandLineInternal(CommandLine.getInstance()); + } + + protected void initCommandLineInternal(CommandLine commandLine) {} +}
diff --git a/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java b/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java new file mode 100644 index 0000000..b3195bb --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridge.java
@@ -0,0 +1,93 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.common; + +import android.content.Context; +import android.os.Handler; +import android.os.HandlerThread; +import android.support.annotation.NonNull; + +import org.chromium.base.Callback; +import org.chromium.base.ThreadUtils; + +/** + * This class manages platform-specific services. (i.e. Google Services) The platform + * should extend this class and use this base class to fetch their specialized version. + */ +public abstract class PlatformServiceBridge { + private static final String TAG = "PlatformServiceBrid-"; + + private static PlatformServiceBridge sInstance; + private static final Object sInstanceLock = new Object(); + + private static HandlerThread sHandlerThread; + private static Handler sHandler; + private static final Object sHandlerLock = new Object(); + + protected PlatformServiceBridge() {} + + @SuppressWarnings("unused") + public static PlatformServiceBridge getInstance() { + synchronized (sInstanceLock) { + if (sInstance == null) { + // Load an instance of PlatformServiceBridgeImpl. Because this can change + // depending on the GN configuration, this may not be the PlatformServiceBridgeImpl + // defined upstream. + sInstance = new PlatformServiceBridgeImpl(); + } + return sInstance; + } + } + + // Provide a mocked PlatformServiceBridge for testing. + public static void injectInstance(PlatformServiceBridge testBridge) { + // Although reference assignments are atomic, we still wouldn't want to assign it in the + // middle of getInstance(). + synchronized (sInstanceLock) { + sInstance = testBridge; + } + } + + // Return a handler appropriate for executing blocking Platform Service tasks. + public static Handler getHandler() { + synchronized (sHandlerLock) { + if (sHandler == null) { + sHandlerThread = new HandlerThread("PlatformServiceBridgeHandlerThread"); + sHandlerThread.start(); + sHandler = new Handler(sHandlerThread.getLooper()); + } + } + return sHandler; + } + + // Can WebView use Google Play Services (a.k.a. GMS)? + public boolean canUseGms() { + return false; + } + + // Overriding implementations may call "callback" asynchronously, on any thread. + public void querySafeBrowsingUserConsent(@NonNull final Callback<Boolean> callback) { + // User opt-in preference depends on a SafetyNet API. + } + + // Overriding implementations may call "callback" asynchronously. For simplicity (and not + // because of any technical limitation) we require that "queryMetricsSetting" and "callback" + // both get called on WebView's UI thread. + public void queryMetricsSetting(Callback<Boolean> callback) { + ThreadUtils.assertOnUiThread(); + callback.onResult(false); + } + + public void setSafeBrowsingHandler() { + // We don't have this specialized service. + } + + public void warmUpSafeBrowsing(Context context, @NonNull final Callback<Boolean> callback) { + callback.onResult(false); + } + + // Takes an uncompressed, serialized UMA proto and logs it via a platform-specific mechanism. + public void logMetrics(byte[] data) {} +}
diff --git a/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridgeImpl.java b/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridgeImpl.java new file mode 100644 index 0000000..c5c6824 --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/common/PlatformServiceBridgeImpl.java
@@ -0,0 +1,13 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.common; + +/** + * Instantiable version of {@link PlatformServiceBridge}, don't add anything to this class! + * Downstream targets may provide a different implementation. In GN, we specify that + * {@link PlatformServiceBridge} is compiled separately from its implementation; other + * projects may specify a different PlatformServiceBridgeImpl via GN. + */ +public class PlatformServiceBridgeImpl extends PlatformServiceBridge {}
diff --git a/android_webview/java/src/org/chromium/android_webview/common/crash/CrashInfo.java b/android_webview/java/src/org/chromium/android_webview/common/crash/CrashInfo.java new file mode 100644 index 0000000..24ef232 --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/common/crash/CrashInfo.java
@@ -0,0 +1,154 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview.common.crash; + +import android.support.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.InvalidObjectException; +import java.util.ArrayList; +import java.util.List; + +/** + * A class that bundles various information about a crash. + */ +public class CrashInfo { + /** + * Crash file report/minidump upload status. + */ + public static enum UploadState { + SKIPPED, + PENDING, + PENDING_USER_REQUESTED, + UPLOADED, + } + + /** + * Upload state for the crash. + */ + public UploadState uploadState; + + /** + * ID for locally stored data that may or may not be uploaded. + */ + @NonNull + public String localId; + /** + * The time the data was captured. This is useful if the data is stored locally when + * captured and uploaded at a later time. + */ + public long captureTime = -1; + /** + * The application package name where a crash happened. + */ + public String packageName; + /** + * List of variation/experiment keys activated when the crash happened. + */ + public List<String> variations; + + /** + * ID the crash collecting servers responded with after the crash report is uploaded. + * Only valid when |uploadState| == Uploaded. + */ + public String uploadId; + /** + * The time when the crash report is uploaded. + * Only valid when |uploadState| == Uploaded. + */ + public long uploadTime = -1; + + private static final String CRASH_LOCAL_ID_KEY = "crash-local-id"; + private static final String CRASH_CAPTURE_TIME_KEY = "crash-capture-time"; + private static final String CRASH_PACKAGE_NAME_KEY = "app-package-name"; + private static final String CRASH_VARIATIONS_KEY = "variations"; + private static final String CRASH_UPLOAD_ID_KEY = "crash-upload-id"; + private static final String CRASH_UPLOAD_TIME_KEY = "crash-upload-time"; + + /** + * Create a {@code CrashInfo} object with a non-null localId. + * This Enforces that localId can never be null, hence eliminate the need for null check. + * localId should always has a non-null value because it used to join crash info from + * different sources together. + */ + public CrashInfo(@NonNull String localId) { + this.localId = localId; + } + + /** + * Serialize {@code CrashInfo} object into a JSON object string. + * + * @return serialized string for the object. + */ + public String serializeToJson() { + try { + JSONObject jsonObj = new JSONObject(); + jsonObj.put(CRASH_LOCAL_ID_KEY, localId); + if (captureTime != -1) { + jsonObj.put(CRASH_CAPTURE_TIME_KEY, captureTime); + } + if (packageName != null) { + jsonObj.put(CRASH_PACKAGE_NAME_KEY, packageName); + } + if (variations != null && !variations.isEmpty()) { + jsonObj.put(CRASH_VARIATIONS_KEY, new JSONArray(variations)); + } + if (uploadId != null) { + jsonObj.put(CRASH_UPLOAD_ID_KEY, uploadId); + } + if (uploadTime != -1) { + jsonObj.put(CRASH_UPLOAD_TIME_KEY, uploadTime); + } + return jsonObj.toString(); + } catch (JSONException e) { + return null; + } + } + + /** + * Load {@code CrashInfo} from a JSON string. + * + * @param jsonString JSON string to load {@code CrashInfo} from. + * @return {@code CrashInfo} loaded from the serialized JSON object string. + * @throws JSONException if it's a malformatted JSON string. + * @throws InvalidObjectException if the JSON Object doesn't have "crash-local-id" field. + */ + public static CrashInfo readFromJsonString(String jsonString) + throws JSONException, InvalidObjectException { + JSONObject jsonObj = new JSONObject(jsonString); + if (!jsonObj.has(CRASH_LOCAL_ID_KEY)) { + throw new InvalidObjectException( + "JSON Object doesn't have the field " + CRASH_LOCAL_ID_KEY); + } + CrashInfo crashInfo = new CrashInfo(jsonObj.getString(CRASH_LOCAL_ID_KEY)); + + if (jsonObj.has(CRASH_CAPTURE_TIME_KEY)) { + crashInfo.captureTime = jsonObj.getLong(CRASH_CAPTURE_TIME_KEY); + } + if (jsonObj.has(CRASH_PACKAGE_NAME_KEY)) { + crashInfo.packageName = jsonObj.getString(CRASH_PACKAGE_NAME_KEY); + } + if (jsonObj.has(CRASH_VARIATIONS_KEY)) { + JSONArray variationsJSONArr = jsonObj.getJSONArray(CRASH_VARIATIONS_KEY); + if (variationsJSONArr != null) { + crashInfo.variations = new ArrayList<>(); + for (int i = 0; i < variationsJSONArr.length(); i++) { + crashInfo.variations.add(variationsJSONArr.getString(i)); + } + } + } + if (jsonObj.has(CRASH_UPLOAD_ID_KEY)) { + crashInfo.uploadId = jsonObj.getString(CRASH_UPLOAD_ID_KEY); + } + if (jsonObj.has(CRASH_UPLOAD_TIME_KEY)) { + crashInfo.uploadTime = jsonObj.getLong(CRASH_UPLOAD_TIME_KEY); + } + + return crashInfo; + } +}
diff --git a/android_webview/java/src/org/chromium/android_webview/VariationsUtils.java b/android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java similarity index 85% rename from android_webview/java/src/org/chromium/android_webview/VariationsUtils.java rename to android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java index 74f2c932..a6e3c80 100644 --- a/android_webview/java/src/org/chromium/android_webview/VariationsUtils.java +++ b/android_webview/java/src/org/chromium/android_webview/common/variations/VariationsUtils.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.android_webview; +package org.chromium.android_webview.common.variations; import android.support.annotation.Nullable; @@ -57,8 +57,8 @@ File oldSeedFile = getSeedFile(); File newSeedFile = getNewSeedFile(); if (!newSeedFile.renameTo(oldSeedFile)) { - Log.e(TAG, "Failed to replace old seed " + oldSeedFile + - " with new seed " + newSeedFile); + Log.e(TAG, + "Failed to replace old seed " + oldSeedFile + " with new seed " + newSeedFile); } } @@ -103,11 +103,9 @@ return null; } - if (!proto.hasSignature() || - !proto.hasCountry() || - !proto.hasDate() || - !proto.hasIsGzipCompressed() || - !proto.hasSeedData()) return null; + if (!proto.hasSignature() || !proto.hasCountry() || !proto.hasDate() + || !proto.hasIsGzipCompressed() || !proto.hasSeedData()) + return null; SeedInfo info = new SeedInfo(); info.signature = proto.getSignature(); @@ -136,12 +134,12 @@ public static boolean writeSeed(FileOutputStream out, SeedInfo info) { try { AwVariationsSeed proto = AwVariationsSeed.newBuilder() - .setSignature(info.signature) - .setCountry(info.country) - .setDate(info.date) - .setIsGzipCompressed(info.isGzipCompressed) - .setSeedData(ByteString.copyFrom(info.seedData)) - .build(); + .setSignature(info.signature) + .setCountry(info.country) + .setDate(info.date) + .setIsGzipCompressed(info.isGzipCompressed) + .setSeedData(ByteString.copyFrom(info.seedData)) + .build(); proto.writeTo(out); return true; } catch (IOException e) {
diff --git a/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java b/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java index 64e8fcb..f941627 100644 --- a/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java +++ b/android_webview/java/src/org/chromium/android_webview/services/AwMinidumpUploaderDelegate.java
@@ -7,8 +7,8 @@ import android.content.Context; import android.net.ConnectivityManager; -import org.chromium.android_webview.PlatformServiceBridge; -import org.chromium.android_webview.command_line.CommandLineUtil; +import org.chromium.android_webview.common.CommandLineUtil; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils;
diff --git a/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java b/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java index a7f076a..b64c830 100644 --- a/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java +++ b/android_webview/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
@@ -13,7 +13,7 @@ import android.content.Context; import android.os.Build; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.compat.ApiHelperForN;
diff --git a/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java b/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java index b2c5483c..dbfb98802 100644 --- a/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java +++ b/android_webview/java/src/org/chromium/android_webview/services/CrashReceiverService.java
@@ -12,7 +12,7 @@ import android.os.IBinder; import android.os.ParcelFileDescriptor; -import org.chromium.android_webview.ui.util.CrashInfoLoader.CrashInfo; +import org.chromium.android_webview.common.crash.CrashInfo; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting;
diff --git a/android_webview/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java b/android_webview/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java index 24ea238..c427cdb 100644 --- a/android_webview/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java +++ b/android_webview/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java
@@ -9,7 +9,7 @@ import android.os.ParcelFileDescriptor; import android.support.annotation.VisibleForTesting; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.base.Log; import org.chromium.components.variations.firstrun.VariationsSeedFetcher.SeedInfo;
diff --git a/android_webview/java/src/org/chromium/android_webview/ui/util/CrashInfoLoader.java b/android_webview/java/src/org/chromium/android_webview/ui/util/CrashInfoLoader.java index 800209b9..480fef1 100644 --- a/android_webview/java/src/org/chromium/android_webview/ui/util/CrashInfoLoader.java +++ b/android_webview/java/src/org/chromium/android_webview/ui/util/CrashInfoLoader.java
@@ -1,16 +1,11 @@ // Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + package org.chromium.android_webview.ui.util; -import android.support.annotation.NonNull; +import org.chromium.android_webview.common.crash.CrashInfo; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.InvalidObjectException; -import java.util.ArrayList; import java.util.List; /** @@ -18,145 +13,6 @@ */ public abstract class CrashInfoLoader { /** - * Crash file report/minidump upload status. - */ - public static enum UploadState { - SKIPPED, - PENDING, - PENDING_USER_REQUESTED, - UPLOADED, - } - - /** - * A class that bundles various information about a crash. - */ - public static class CrashInfo { - /** - * Upload state for the crash. - */ - public UploadState uploadState; - - /** - * ID for locally stored data that may or may not be uploaded. - */ - @NonNull - public String localId; - /** - * The time the data was captured. This is useful if the data is stored locally when - * captured and uploaded at a later time. - */ - public long captureTime = -1; - /** - * The application package name where a crash happened. - */ - public String packageName; - /** - * List of variation/experiment keys activated when the crash happened. - */ - public List<String> variations; - - /** - * ID the crash collecting servers responded with after the crash report is uploaded. - * Only valid when |uploadState| == Uploaded. - */ - public String uploadId; - /** - * The time when the crash report is uploaded. - * Only valid when |uploadState| == Uploaded. - */ - public long uploadTime = -1; - - private static final String CRASH_LOCAL_ID_KEY = "crash-local-id"; - private static final String CRASH_CAPTURE_TIME_KEY = "crash-capture-time"; - private static final String CRASH_PACKAGE_NAME_KEY = "app-package-name"; - private static final String CRASH_VARIATIONS_KEY = "variations"; - private static final String CRASH_UPLOAD_ID_KEY = "crash-upload-id"; - private static final String CRASH_UPLOAD_TIME_KEY = "crash-upload-time"; - - /** - * Create a {@code CrashInfo} object with a non-null localId. - * This Enforces that localId can never be null, hence eliminate the need for null check. - * localId should always has a non-null value because it used to join crash info from - * different sources together. - */ - public CrashInfo(@NonNull String localId) { - this.localId = localId; - } - - /** - * Serialize {@code CrashInfo} object into a JSON object string. - * - * @return serialized string for the object. - */ - public String serializeToJson() { - try { - JSONObject jsonObj = new JSONObject(); - jsonObj.put(CRASH_LOCAL_ID_KEY, localId); - if (captureTime != -1) { - jsonObj.put(CRASH_CAPTURE_TIME_KEY, captureTime); - } - if (packageName != null) { - jsonObj.put(CRASH_PACKAGE_NAME_KEY, packageName); - } - if (variations != null && !variations.isEmpty()) { - jsonObj.put(CRASH_VARIATIONS_KEY, new JSONArray(variations)); - } - if (uploadId != null) { - jsonObj.put(CRASH_UPLOAD_ID_KEY, uploadId); - } - if (uploadTime != -1) { - jsonObj.put(CRASH_UPLOAD_TIME_KEY, uploadTime); - } - return jsonObj.toString(); - } catch (JSONException e) { - return null; - } - } - - /** - * Load {@code CrashInfo} from a JSON string. - * - * @param jsonString JSON string to load {@code CrashInfo} from. - * @return {@code CrashInfo} loaded from the serialized JSON object string. - * @throws JSONException if it's a malformatted JSON string. - * @throws InvalidObjectException if the JSON Object doesn't have "crash-local-id" field. - */ - public static CrashInfo readFromJsonString(String jsonString) - throws JSONException, InvalidObjectException { - JSONObject jsonObj = new JSONObject(jsonString); - if (!jsonObj.has(CRASH_LOCAL_ID_KEY)) { - throw new InvalidObjectException( - "JSON Object doesn't have the field " + CRASH_LOCAL_ID_KEY); - } - CrashInfo crashInfo = new CrashInfo(jsonObj.getString(CRASH_LOCAL_ID_KEY)); - - if (jsonObj.has(CRASH_CAPTURE_TIME_KEY)) { - crashInfo.captureTime = jsonObj.getLong(CRASH_CAPTURE_TIME_KEY); - } - if (jsonObj.has(CRASH_PACKAGE_NAME_KEY)) { - crashInfo.packageName = jsonObj.getString(CRASH_PACKAGE_NAME_KEY); - } - if (jsonObj.has(CRASH_VARIATIONS_KEY)) { - JSONArray variationsJSONArr = jsonObj.getJSONArray(CRASH_VARIATIONS_KEY); - if (variationsJSONArr != null) { - crashInfo.variations = new ArrayList<>(); - for (int i = 0; i < variationsJSONArr.length(); i++) { - crashInfo.variations.add(variationsJSONArr.getString(i)); - } - } - } - if (jsonObj.has(CRASH_UPLOAD_ID_KEY)) { - crashInfo.uploadId = jsonObj.getString(CRASH_UPLOAD_ID_KEY); - } - if (jsonObj.has(CRASH_UPLOAD_TIME_KEY)) { - crashInfo.uploadTime = jsonObj.getLong(CRASH_UPLOAD_TIME_KEY); - } - - return crashInfo; - } - } - - /** * Loads all crashes info from source. * * @return list of crashes info.
diff --git a/android_webview/java/src/org/chromium/android_webview/ui/util/UnuploadedFilesStateLoader.java b/android_webview/java/src/org/chromium/android_webview/ui/util/UnuploadedFilesStateLoader.java index 4f4dc3d7..69816a01 100644 --- a/android_webview/java/src/org/chromium/android_webview/ui/util/UnuploadedFilesStateLoader.java +++ b/android_webview/java/src/org/chromium/android_webview/ui/util/UnuploadedFilesStateLoader.java
@@ -3,6 +3,8 @@ // found in the LICENSE file. package org.chromium.android_webview.ui.util; +import org.chromium.android_webview.common.crash.CrashInfo; +import org.chromium.android_webview.common.crash.CrashInfo.UploadState; import org.chromium.components.minidump_uploader.CrashFileManager; import java.io.File;
diff --git a/android_webview/java/src/org/chromium/android_webview/ui/util/UploadedCrashesInfoLoader.java b/android_webview/java/src/org/chromium/android_webview/ui/util/UploadedCrashesInfoLoader.java index 54095c5..e9ac867 100644 --- a/android_webview/java/src/org/chromium/android_webview/ui/util/UploadedCrashesInfoLoader.java +++ b/android_webview/java/src/org/chromium/android_webview/ui/util/UploadedCrashesInfoLoader.java
@@ -1,8 +1,11 @@ // Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + package org.chromium.android_webview.ui.util; +import org.chromium.android_webview.common.crash.CrashInfo; + import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -62,7 +65,7 @@ } CrashInfo info = new CrashInfo(components[2]); - info.uploadState = UploadState.UPLOADED; + info.uploadState = CrashInfo.UploadState.UPLOADED; try { info.uploadTime = Long.parseLong(components[0]); } catch (NumberFormatException e) {
diff --git a/android_webview/java/src/org/chromium/android_webview/ui/util/WebViewCrashLogParser.java b/android_webview/java/src/org/chromium/android_webview/ui/util/WebViewCrashLogParser.java index 3bac1d8e..2f0f6714 100644 --- a/android_webview/java/src/org/chromium/android_webview/ui/util/WebViewCrashLogParser.java +++ b/android_webview/java/src/org/chromium/android_webview/ui/util/WebViewCrashLogParser.java
@@ -1,10 +1,12 @@ // Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. + package org.chromium.android_webview.ui.util; import org.json.JSONException; +import org.chromium.android_webview.common.crash.CrashInfo; import org.chromium.base.Log; import java.io.File;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java index d0798836e..762dffd 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwVariationsSeedFetcherTest.java
@@ -21,7 +21,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.android_webview.services.AwVariationsSeedFetcher; import org.chromium.android_webview.test.util.VariationsTestUtils; import org.chromium.base.ContextUtils;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java index 931dbac..becc222 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java
@@ -15,7 +15,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.android_webview.services.VariationsSeedHolder; import org.chromium.android_webview.test.util.VariationsTestUtils; import org.chromium.base.test.util.CallbackHelper;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java index 4733a80..2c2634f 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java
@@ -18,7 +18,7 @@ import org.junit.runner.RunWith; import org.chromium.android_webview.VariationsSeedLoader; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.android_webview.test.services.MockVariationsSeedServer; import org.chromium.android_webview.test.util.VariationsTestUtils; import org.chromium.base.ContextUtils;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsUtilsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/common/variations/VariationsUtilsTest.java similarity index 76% rename from android_webview/javatests/src/org/chromium/android_webview/test/VariationsUtilsTest.java rename to android_webview/javatests/src/org/chromium/android_webview/test/common/variations/VariationsUtilsTest.java index f6089de..47182ab2 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/VariationsUtilsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/common/variations/VariationsUtilsTest.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.android_webview.test; +package org.chromium.android_webview.test.common.variations; import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS; @@ -14,8 +14,10 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.android_webview.proto.AwVariationsSeedOuterClass.AwVariationsSeed; +import org.chromium.android_webview.test.AwJUnit4ClassRunner; +import org.chromium.android_webview.test.OnlyRunIn; import org.chromium.android_webview.test.util.VariationsTestUtils; import org.chromium.components.variations.firstrun.VariationsSeedFetcher.SeedInfo; @@ -57,10 +59,10 @@ stream = new FileOutputStream(file); SeedInfo info = VariationsTestUtils.createMockSeed(); AwVariationsSeed proto = AwVariationsSeed.newBuilder() - .setSignature(info.signature) - .setCountry(info.country) - .setDate(info.date) - .build(); + .setSignature(info.signature) + .setCountry(info.country) + .setDate(info.date) + .build(); proto.writeTo(stream); Assert.assertNull("Seed with missing fields should've failed to load.", @@ -80,12 +82,12 @@ // Create a complete, serialized seed. SeedInfo info = VariationsTestUtils.createMockSeed(); AwVariationsSeed proto = AwVariationsSeed.newBuilder() - .setSignature(info.signature) - .setCountry(info.country) - .setDate(info.date) - .setIsGzipCompressed(info.isGzipCompressed) - .setSeedData(ByteString.copyFrom(info.seedData)) - .build(); + .setSignature(info.signature) + .setCountry(info.country) + .setDate(info.date) + .setIsGzipCompressed(info.isGzipCompressed) + .setSeedData(ByteString.copyFrom(info.seedData)) + .build(); byte[] protoBytes = proto.toByteArray(); // Sanity check: protoBytes is at least as long as the seedData field. @@ -106,8 +108,9 @@ } // Reading each truncated seed should fail. - Assert.assertNull("Seed truncated from " + protoBytes.length + " to " + offset + - " bytes should've failed to load.", VariationsUtils.readSeedFile(file)); + Assert.assertNull("Seed truncated from " + protoBytes.length + " to " + offset + + " bytes should've failed to load.", + VariationsUtils.readSeedFile(file)); } finally { if (file != null) file.delete(); }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java index 19bff37..4027c6c 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java
@@ -16,10 +16,10 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; +import org.chromium.android_webview.common.crash.CrashInfo; import org.chromium.android_webview.services.CrashReceiverService; import org.chromium.android_webview.test.AwJUnit4ClassRunner; import org.chromium.android_webview.test.OnlyRunIn; -import org.chromium.android_webview.ui.util.CrashInfoLoader.CrashInfo; import java.io.File; import java.io.FileInputStream;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploaderTest.java index 5944242..1a2c7c5c 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploaderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/MinidumpUploaderTest.java
@@ -14,7 +14,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.android_webview.PlatformServiceBridge; +import org.chromium.android_webview.common.PlatformServiceBridge; import org.chromium.android_webview.services.AwMinidumpUploaderDelegate; import org.chromium.android_webview.services.CrashReceiverService; import org.chromium.android_webview.test.AwJUnit4ClassRunner;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UnuploadedFilesStateLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UnuploadedFilesStateLoaderTest.java index ac62392f9..33e0bf22 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UnuploadedFilesStateLoaderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UnuploadedFilesStateLoaderTest.java
@@ -15,10 +15,10 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; +import org.chromium.android_webview.common.crash.CrashInfo; +import org.chromium.android_webview.common.crash.CrashInfo.UploadState; import org.chromium.android_webview.test.AwJUnit4ClassRunner; import org.chromium.android_webview.test.OnlyRunIn; -import org.chromium.android_webview.ui.util.CrashInfoLoader.CrashInfo; -import org.chromium.android_webview.ui.util.CrashInfoLoader.UploadState; import org.chromium.android_webview.ui.util.UnuploadedFilesStateLoader; import org.chromium.components.minidump_uploader.CrashFileManager;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UploadedCrashesInfoLoaderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UploadedCrashesInfoLoaderTest.java index c7b45c4..36b7d47 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UploadedCrashesInfoLoaderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/UploadedCrashesInfoLoaderTest.java
@@ -14,10 +14,10 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.android_webview.common.crash.CrashInfo; +import org.chromium.android_webview.common.crash.CrashInfo.UploadState; import org.chromium.android_webview.test.AwJUnit4ClassRunner; import org.chromium.android_webview.test.OnlyRunIn; -import org.chromium.android_webview.ui.util.CrashInfoLoader.CrashInfo; -import org.chromium.android_webview.ui.util.CrashInfoLoader.UploadState; import org.chromium.android_webview.ui.util.UploadedCrashesInfoLoader; import java.io.BufferedWriter;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/WebViewCrashLogParserTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/WebViewCrashLogParserTest.java index 08fc773..0a3e673e 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/WebViewCrashLogParserTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/ui/util/WebViewCrashLogParserTest.java
@@ -15,8 +15,8 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; +import org.chromium.android_webview.common.crash.CrashInfo; import org.chromium.android_webview.test.AwJUnit4ClassRunner; -import org.chromium.android_webview.ui.util.CrashInfoLoader.CrashInfo; import org.chromium.android_webview.ui.util.WebViewCrashLogParser; import java.io.File;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/VariationsTestUtils.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/VariationsTestUtils.java index 3e57094..538cdf5 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/util/VariationsTestUtils.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/VariationsTestUtils.java
@@ -6,7 +6,7 @@ import org.junit.Assert; -import org.chromium.android_webview.VariationsUtils; +import org.chromium.android_webview.common.variations.VariationsUtils; import org.chromium.components.variations.firstrun.VariationsSeedFetcher.SeedInfo; import java.io.File;
diff --git a/android_webview/support_library/BUILD.gn b/android_webview/support_library/BUILD.gn index 48f7933..f09fece 100644 --- a/android_webview/support_library/BUILD.gn +++ b/android_webview/support_library/BUILD.gn
@@ -26,7 +26,6 @@ ] deps = [ - "//android_webview:android_webview_commandline_java", "//android_webview:android_webview_java", "//android_webview/glue:glue", "//android_webview/support_library/boundary_interfaces:boundary_interface_java",
diff --git a/android_webview/support_library/callback/BUILD.gn b/android_webview/support_library/callback/BUILD.gn index 214eeb0..b4886e5 100644 --- a/android_webview/support_library/callback/BUILD.gn +++ b/android_webview/support_library/callback/BUILD.gn
@@ -13,7 +13,6 @@ ] deps = [ - "//android_webview:android_webview_commandline_java", "//android_webview:android_webview_java", "//android_webview/support_library/boundary_interfaces:boundary_interface_java", "//base:base_java",
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index b35379b..0bb992a 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -48,10 +48,10 @@ ":android_webview_apk_resources", "//android_webview:android_webview_java", "//android_webview:android_webview_locale_config_java", + "//android_webview:common_java", "//android_webview:locale_pak_assets", "//android_webview:platform_service_bridge_upstream_implementation_java", "//android_webview/apk:apk_java", - "//android_webview/common:common_java", "//base:base_java", "//base:base_java_test_support", "//components/heap_profiling:heap_profiling_java_test_support", @@ -156,7 +156,6 @@ min_sdk_version = 21 deps = [ "//android_webview:android_webview_java", - "//android_webview:android_webview_platform_services_java", "//android_webview:android_webview_services_java", "//android_webview:aw_variations_seed_server_aidl", "//android_webview/test/embedded_test_server:aw_net_java_test_support", @@ -270,13 +269,13 @@ "../javatests/src/org/chromium/android_webview/test/UserAgentTest.java", "../javatests/src/org/chromium/android_webview/test/VariationsSeedHolderTest.java", "../javatests/src/org/chromium/android_webview/test/VariationsSeedLoaderTest.java", - "../javatests/src/org/chromium/android_webview/test/VariationsUtilsTest.java", "../javatests/src/org/chromium/android_webview/test/VisualStateTest.java", "../javatests/src/org/chromium/android_webview/test/WebKitHitTestTest.java", "../javatests/src/org/chromium/android_webview/test/WebViewAsynchronousFindApisTest.java", "../javatests/src/org/chromium/android_webview/test/WebViewFindApisTestRule.java", "../javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java", "../javatests/src/org/chromium/android_webview/test/WebViewWebVrTest.java", + "../javatests/src/org/chromium/android_webview/test/common/variations/VariationsUtilsTest.java", "../javatests/src/org/chromium/android_webview/test/services/CrashReceiverServiceTest.java", "../javatests/src/org/chromium/android_webview/test/services/MinidumpUploaderTest.java", "../javatests/src/org/chromium/android_webview/test/services/MockVariationsSeedServer.java",
diff --git a/ash/media/media_notification_controller_impl.cc b/ash/media/media_notification_controller_impl.cc index 85afaee..1d2a61a6 100644 --- a/ash/media/media_notification_controller_impl.cc +++ b/ash/media/media_notification_controller_impl.cc
@@ -137,7 +137,10 @@ media_session::mojom::AudioFocusRequestStatePtr session) { const std::string id = session->request_id->ToString(); - if (base::Contains(notifications_, id)) + // If we have an existing unfrozen item then this is a duplicate call and + // we should ignore it. + auto it = notifications_.find(id); + if (it != notifications_.end() && !it->second.frozen()) return; media_session::mojom::MediaControllerPtr controller; @@ -149,16 +152,29 @@ mojo::MakeRequest(&controller), *session->request_id); } - notifications_.emplace( - std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple( - this, id, session->source_name.value_or(std::string()), - std::move(controller), std::move(session->session_info))); + if (it != notifications_.end()) { + // If the notification was previously frozen then we should reset the + // controller because the mojo pipe would have been reset. + it->second.SetController(std::move(controller), + std::move(session->session_info)); + } else { + notifications_.emplace( + std::piecewise_construct, std::forward_as_tuple(id), + std::forward_as_tuple( + this, id, session->source_name.value_or(std::string()), + std::move(controller), std::move(session->session_info))); + } } void MediaNotificationControllerImpl::OnFocusLost( media_session::mojom::AudioFocusRequestStatePtr session) { - notifications_.erase(session->request_id->ToString()); + auto it = notifications_.find(session->request_id->ToString()); + if (it == notifications_.end()) + return; + + // If we lost focus then we should freeze the notification as it may regain + // focus after a second or so. + it->second.Freeze(); } void MediaNotificationControllerImpl::ShowNotification(const std::string& id) { @@ -192,6 +208,15 @@ message_center::MessageCenter::Get()->RemoveNotification(id, false); } +void MediaNotificationControllerImpl::RemoveItem(const std::string& id) { + notifications_.erase(id); +} + +scoped_refptr<base::SequencedTaskRunner> +MediaNotificationControllerImpl::GetTaskRunner() const { + return task_runner_for_testing_; +} + std::unique_ptr<MediaNotificationContainerImpl> MediaNotificationControllerImpl::CreateMediaNotification( const message_center::Notification& notification) { @@ -205,6 +230,11 @@ std::move(item)); } +bool MediaNotificationControllerImpl::HasItemForTesting( + const std::string& id) const { + return base::Contains(notifications_, id); +} + void MediaNotificationControllerImpl::RecordConcurrentNotificationCount() { UMA_HISTOGRAM_EXACT_LINEAR( kCountHistogramName,
diff --git a/ash/media/media_notification_controller_impl.h b/ash/media/media_notification_controller_impl.h index bc6db4c3..826d803b 100644 --- a/ash/media/media_notification_controller_impl.h +++ b/ash/media/media_notification_controller_impl.h
@@ -57,6 +57,8 @@ // media_message_center::MediaNotificationController: void ShowNotification(const std::string& id) override; void HideNotification(const std::string& id) override; + void RemoveItem(const std::string& id) override; + scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override; std::unique_ptr<MediaNotificationContainerImpl> CreateMediaNotification( const message_center::Notification& notification); @@ -67,6 +69,12 @@ return &it->second; } + bool HasItemForTesting(const std::string& id) const; + void set_task_runner_for_testing( + scoped_refptr<base::SequencedTaskRunner> task_runner_for_testing) { + task_runner_for_testing_ = task_runner_for_testing; + } + private: // Called when we display a new media notification. It will record the // concurrent number of media notifications displayed. @@ -82,6 +90,9 @@ std::map<const std::string, media_message_center::MediaNotificationItem> notifications_; + // Tick clock used for testing. + scoped_refptr<base::SequencedTaskRunner> task_runner_for_testing_; + std::unique_ptr<MediaNotificationBlocker> blocker_; DISALLOW_COPY_AND_ASSIGN(MediaNotificationControllerImpl);
diff --git a/ash/media/media_notification_controller_impl_unittest.cc b/ash/media/media_notification_controller_impl_unittest.cc index 204a56bc..73ee7432 100644 --- a/ash/media/media_notification_controller_impl_unittest.cc +++ b/ash/media/media_notification_controller_impl_unittest.cc
@@ -16,6 +16,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "base/test/test_mock_time_task_runner.h" #include "base/unguessable_token.h" #include "components/media_message_center/media_notification_item.h" #include "services/media_session/public/mojom/audio_focus.mojom.h" @@ -46,7 +47,10 @@ class MediaNotificationControllerImplTest : public AshTestBase { public: - MediaNotificationControllerImplTest() = default; + MediaNotificationControllerImplTest() + : task_runner_(new base::TestMockTimeTaskRunner( + base::TestMockTimeTaskRunner::Type::kStandalone)) {} + ~MediaNotificationControllerImplTest() override = default; // AshTestBase @@ -55,6 +59,9 @@ features::kMediaSessionNotification); AshTestBase::SetUp(); + + Shell::Get()->media_notification_controller()->set_task_runner_for_testing( + task_runner_); } void ExpectNotificationCount(unsigned count) { @@ -94,7 +101,13 @@ Shell::Get()->session_controller()->SetSessionInfo(info); } + void SimulateFreezeTimerExpired() { + task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(2500)); + } + private: + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; + base::test::ScopedFeatureList scoped_feature_list_; base::HistogramTester histogram_tester_; @@ -128,6 +141,7 @@ Shell::Get()->media_notification_controller()->OnFocusLost( GetRequestStateWithId(id)); + SimulateFreezeTimerExpired(); ExpectNotificationCount(0); } @@ -164,6 +178,7 @@ Shell::Get()->media_notification_controller()->OnFocusLost( GetRequestStateWithId(id1)); + SimulateFreezeTimerExpired(); ExpectNotificationCount(1); ExpectHistogramCountRecorded(1, 1); @@ -475,4 +490,255 @@ EXPECT_EQ(2u, message_center->GetVisibleNotifications().size()); } +// Test that when we lose focus we freeze the notification until the timer +// is fired and then remove it. +TEST_F(MediaNotificationControllerImplTest, OnFocusLostFreezeUntilTimerFired) { + base::UnguessableToken id = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + ExpectNotificationCount(1); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + SimulateFreezeTimerExpired(); + ExpectNotificationCount(0); +} + +// Test that when we lose focus we freeze the notification and then we see +// the session resume we keep the notification and unfreeze it. +TEST_F(MediaNotificationControllerImplTest, OnFocusLostFreezeAndResumeSameId) { + base::UnguessableToken id = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + ExpectNotificationCount(1); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + // The session comes back and is controllable so we should unfreeze the + // notification. + ExpectNotificationCount(1); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); +} + +// Test that when we lose focus we freeze the notification and then we see +// the session resume but it is missing metadata we hide the notification. +TEST_F(MediaNotificationControllerImplTest, + OnFocusLostFreezeAndResumeSameId_MissingMetadata) { + base::UnguessableToken id = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + ExpectNotificationCount(1); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(media_session::MediaMetadata()); + + // The session has come back but the metadata is missing data so we should + // keep the notification frozen. + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + // After the timer has been fired we should hide the notification but still + // have the controller. + SimulateFreezeTimerExpired(); + ExpectNotificationCount(0); + EXPECT_TRUE(Shell::Get()->media_notification_controller()->HasItemForTesting( + id.ToString())); +} + +// Test that when we lose focus we freeze the notification and then we see +// the session resume but it is not controllable we hide the notification. +TEST_F(MediaNotificationControllerImplTest, + OnFocusLostFreezeAndResumeSameId_NotControllable) { + base::UnguessableToken id = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + ExpectNotificationCount(1); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id)); + + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + media_session::mojom::AudioFocusRequestStatePtr state = + GetRequestStateWithId(id); + state->session_info->is_controllable = false; + Shell::Get()->media_notification_controller()->OnFocusGained( + std::move(state)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + // The session has come back but the metadata is not controllable so we should + // keep the notification frozen. + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id.ToString()) + ->frozen()); + + // After the timer has been fired we should hide the notification but still + // have the controller. + SimulateFreezeTimerExpired(); + ExpectNotificationCount(0); + EXPECT_TRUE(Shell::Get()->media_notification_controller()->HasItemForTesting( + id.ToString())); +} + +// Test that when we lose focus we freeze the notification and we see a new +// session then that does not unfreeze the first notification. +TEST_F(MediaNotificationControllerImplTest, + OnFocusLostFreezeAndDoNotResumeNewId) { + base::UnguessableToken id1 = base::UnguessableToken::Create(); + base::UnguessableToken id2 = base::UnguessableToken::Create(); + + ExpectNotificationCount(0); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id1)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id1.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + ExpectNotificationCount(1); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id1.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusLost( + GetRequestStateWithId(id1)); + + ExpectNotificationCount(1); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id1.ToString()) + ->frozen()); + + Shell::Get()->media_notification_controller()->OnFocusGained( + GetRequestStateWithId(id2)); + + Shell::Get() + ->media_notification_controller() + ->GetItem(id2.ToString()) + ->MediaSessionMetadataChanged(BuildMediaMetadata()); + + ExpectNotificationCount(2); + EXPECT_TRUE(Shell::Get() + ->media_notification_controller() + ->GetItem(id1.ToString()) + ->frozen()); + EXPECT_FALSE(Shell::Get() + ->media_notification_controller() + ->GetItem(id2.ToString()) + ->frozen()); + + SimulateFreezeTimerExpired(); + ExpectNotificationCount(1); + + EXPECT_FALSE(Shell::Get()->media_notification_controller()->HasItemForTesting( + id1.ToString())); +} + } // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 7c413350..e153863c 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -786,8 +786,7 @@ //////////////////////////////////////////////////////////////////////////////// // ShelfLayoutManager, private: -ShelfLayoutManager::TargetBounds::TargetBounds() - : shelf_opacity(0.0f), status_opacity(0.0f) {} +ShelfLayoutManager::TargetBounds::TargetBounds() : opacity(0.0f) {} ShelfLayoutManager::TargetBounds::~TargetBounds() = default; @@ -912,15 +911,15 @@ return; hide_animation_observer_.reset(); - if (GetLayer(shelf_widget_)->opacity() != target_bounds.shelf_opacity) { - if (target_bounds.shelf_opacity == 0) { + if (GetLayer(shelf_widget_)->opacity() != target_bounds.opacity) { + if (target_bounds.opacity == 0) { // On hide, set the opacity after the animation completes. hide_animation_observer_ = std::make_unique<HideAnimationObserver>(GetLayer(shelf_widget_)); } else { // On show, set the opacity before the animation begins to ensure the blur // is shown while the shelf moves. - GetLayer(shelf_widget_)->SetOpacity(target_bounds.shelf_opacity); + GetLayer(shelf_widget_)->SetOpacity(target_bounds.opacity); } } @@ -966,18 +965,15 @@ &shelf_bounds); shelf_widget_->SetBounds(shelf_bounds); - GetLayer(nav_widget)->SetOpacity(target_bounds.nav_opacity); - GetLayer(status_widget)->SetOpacity(target_bounds.status_opacity); + GetLayer(nav_widget)->SetOpacity(target_bounds.opacity); + GetLayer(status_widget)->SetOpacity(target_bounds.opacity); // Having a window which is visible but does not have an opacity is an // illegal state. We therefore hide the shelf here if required. - if (!target_bounds.status_opacity) - status_widget->Hide(); - - if (state_.IsActiveSessionState() && target_bounds.nav_opacity) - nav_widget->ShowInactive(); - else + if (!target_bounds.opacity) { nav_widget->Hide(); + status_widget->Hide(); + } // Setting visibility during an animation causes the visibility property to // animate. Override the animation settings to immediately set the @@ -1030,8 +1026,11 @@ // Setting visibility during an animation causes the visibility property to // animate. Set the visibility property without an animation. - if (target_bounds.status_opacity) + if (target_bounds.opacity) { + if (state_.IsActiveSessionState()) + nav_widget->ShowInactive(); status_widget->Show(); + } } bool ShelfLayoutManager::IsDraggingWindowFromTopOrCaptionArea() const { @@ -1118,14 +1117,7 @@ target_bounds->nav_bounds_in_shelf = gfx::Rect(nav_origin, shelf_widget_->navigation_widget()->GetIdealSize()); - target_bounds->shelf_opacity = ComputeTargetOpacity(state); - if (state.IsShelfAutoHidden() && drag_status_ != kDragInProgress) { - target_bounds->nav_opacity = 0.0f; - target_bounds->status_opacity = 0.0f; - } else { - target_bounds->nav_opacity = target_bounds->shelf_opacity; - target_bounds->status_opacity = target_bounds->shelf_opacity; - } + target_bounds->opacity = ComputeTargetOpacity(state); if (drag_status_ == kDragInProgress) UpdateTargetBoundsForGesture(target_bounds); @@ -1731,12 +1723,12 @@ } float ShelfLayoutManager::GetAppListBackgroundOpacityOnShelfOpacity() { - float shelf_opacity = shelf_widget_->GetBackgroundAlphaValue( - shelf_background_type_before_drag_) / - static_cast<float>(ShelfBackgroundAnimator::kMaxAlpha); + float opacity = shelf_widget_->GetBackgroundAlphaValue( + shelf_background_type_before_drag_) / + static_cast<float>(ShelfBackgroundAnimator::kMaxAlpha); const int shelf_size = ShelfConstants::shelf_size(); if (launcher_above_shelf_bottom_amount_ < shelf_size) - return shelf_opacity; + return opacity; float launcher_above_shelf_amount = std::max(0.f, launcher_above_shelf_bottom_amount_ - shelf_size); float coefficient = @@ -1747,8 +1739,7 @@ is_background_blur_enabled_ ? app_list::AppListView::kAppListOpacityWithBlur : app_list::AppListView::kAppListOpacity; - return app_list_view_opacity * coefficient + - (1 - coefficient) * shelf_opacity; + return app_list_view_opacity * coefficient + (1 - coefficient) * opacity; } bool ShelfLayoutManager::IsSwipingCorrectDirection() {
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 7f0c60c..850f10cf 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -230,9 +230,7 @@ TargetBounds(); ~TargetBounds(); - float shelf_opacity; - float nav_opacity; - float status_opacity; + float opacity; gfx::Rect shelf_bounds; // Bounds of the shelf within the screen gfx::Rect shelf_bounds_in_shelf; // Bounds of the shelf minus status area
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc index b70f579..5f05565 100644 --- a/ash/wm/overview/overview_grid.cc +++ b/ash/wm/overview/overview_grid.cc
@@ -1283,7 +1283,7 @@ } // |rightmost_window_right| may have been modified by an earlier scroll. // |scroll_offset_| is added to adjust for that. - rightmost_window_right += scroll_offset_; + rightmost_window_right -= scroll_offset_; scroll_offset_min_ = total_bounds.right() - rightmost_window_right; } @@ -1450,9 +1450,10 @@ rects.push_back(gfx::RectF()); continue; } - const int x = - width * (window_position / 2) + total_bounds.x() + scroll_offset_; - const int y = height * (window_position % 2) + total_bounds.y(); + const int x = width * (window_position / kTabletLayoutRow) + + total_bounds.x() + scroll_offset_; + const int y = + height * (window_position % kTabletLayoutRow) + total_bounds.y(); const gfx::RectF bounds(x, y, width, height); rects.push_back(bounds); ++window_position;
diff --git a/ash/wm/overview/overview_grid_pre_event_handler.cc b/ash/wm/overview/overview_grid_pre_event_handler.cc index b80710f..8a025d6e 100644 --- a/ash/wm/overview/overview_grid_pre_event_handler.cc +++ b/ash/wm/overview/overview_grid_pre_event_handler.cc
@@ -18,20 +18,27 @@ namespace { WallpaperView* GetWallpaperViewForRoot(const aura::Window* root_window) { - return RootWindowController::ForWindow(root_window) - ->wallpaper_widget_controller() - ->wallpaper_view(); + auto* wallpaper_widget_controller = + RootWindowController::ForWindow(root_window) + ->wallpaper_widget_controller(); + if (!wallpaper_widget_controller) + return nullptr; + return wallpaper_widget_controller->wallpaper_view(); } } // namespace OverviewGridPreEventHandler::OverviewGridPreEventHandler(OverviewGrid* grid) : grid_(grid) { - GetWallpaperViewForRoot(grid_->root_window())->AddPreTargetHandler(this); + auto* wallpaper_view = GetWallpaperViewForRoot(grid_->root_window()); + if (wallpaper_view) + wallpaper_view->AddPreTargetHandler(this); } OverviewGridPreEventHandler::~OverviewGridPreEventHandler() { - GetWallpaperViewForRoot(grid_->root_window())->RemovePreTargetHandler(this); + auto* wallpaper_view = GetWallpaperViewForRoot(grid_->root_window()); + if (wallpaper_view) + wallpaper_view->RemovePreTargetHandler(this); } void OverviewGridPreEventHandler::OnMouseEvent(ui::MouseEvent* event) {
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc index a1b05cb4..96bea5a 100644 --- a/ash/wm/overview/overview_session_unittest.cc +++ b/ash/wm/overview/overview_session_unittest.cc
@@ -2812,6 +2812,11 @@ EnterTabletMode(); } + void GenerateScrollSequence(const gfx::Point& start, const gfx::Point& end) { + GetEventGenerator()->GestureScrollSequence( + start, end, base::TimeDelta::FromMilliseconds(10), 10); + } + private: base::test::ScopedFeatureList scoped_feature_list_; @@ -2894,6 +2899,73 @@ EXPECT_LT(item6_bounds.y(), item7_bounds.y()); } +// Tests to see if windows are not shifted if all already available windows +// fit on screen. +TEST_F(OverviewSessionNewLayoutTest, CheckNoOverviewItemShift) { + std::vector<std::unique_ptr<aura::Window>> windows(4); + for (int i = 3; i >= 0; --i) + windows[i] = CreateTestWindow(); + + ToggleOverview(); + ASSERT_TRUE(InOverviewSession()); + + OverviewItem* item0 = GetOverviewItemInGridWithWindow(0, windows[0].get()); + const gfx::RectF before_shift_bounds = item0->target_bounds(); + + GenerateScrollSequence(gfx::Point(100, 50), gfx::Point(0, 50)); + EXPECT_EQ(before_shift_bounds, item0->target_bounds()); +} + +// Tests to see if windows are shifted if at least one window is +// partially/completely positioned offscreen. +TEST_F(OverviewSessionNewLayoutTest, CheckOverviewItemShift) { + std::vector<std::unique_ptr<aura::Window>> windows(7); + for (int i = 6; i >= 0; --i) + windows[i] = CreateTestWindow(); + + ToggleOverview(); + ASSERT_TRUE(InOverviewSession()); + + OverviewItem* item0 = GetOverviewItemInGridWithWindow(0, windows[0].get()); + const gfx::RectF before_shift_bounds = item0->target_bounds(); + + GenerateScrollSequence(gfx::Point(100, 50), gfx::Point(0, 50)); + EXPECT_LT(item0->target_bounds(), before_shift_bounds); +} + +// Tests to see if windows remain in bounds after scrolling extremely far. +TEST_F(OverviewSessionNewLayoutTest, CheckOverviewItemScrollingBounds) { + std::vector<std::unique_ptr<aura::Window>> windows(8); + for (int i = 7; i >= 0; --i) + windows[i] = CreateTestWindow(); + + ToggleOverview(); + ASSERT_TRUE(InOverviewSession()); + + // Scroll an extreme amount to see if windows on the far left are still in + // bounds. First, align the left-most window (|windows|0||) to the left-hand + // bound and store the item's location. Then, scroll a far amount and check to + // see if the item moved at all. + OverviewItem* leftmost_window = + GetOverviewItemInGridWithWindow(0, windows[0].get()); + + GenerateScrollSequence(gfx::Point(0, 50), gfx::Point(5000, 50)); + const gfx::RectF left_bounds = leftmost_window->target_bounds(); + GenerateScrollSequence(gfx::Point(0, 50), gfx::Point(5000, 50)); + EXPECT_EQ(left_bounds, leftmost_window->target_bounds()); + + // Scroll an extreme amount to see if windows on the far right are still in + // bounds. First, align the right-most window (|windows|7||) to the right-hand + // bound and store the item's location. Then, scroll a far amount and check to + // see if the item moved at all. + OverviewItem* rightmost_window = + GetOverviewItemInGridWithWindow(0, windows[7].get()); + GenerateScrollSequence(gfx::Point(5000, 50), gfx::Point(0, 50)); + const gfx::RectF right_bounds = rightmost_window->target_bounds(); + GenerateScrollSequence(gfx::Point(5000, 50), gfx::Point(0, 50)); + EXPECT_EQ(right_bounds, rightmost_window->target_bounds()); +} + // Test the split view and overview functionalities in tablet mode. class SplitViewOverviewSessionTest : public OverviewSessionTest { public:
diff --git a/base/BUILD.gn b/base/BUILD.gn index 604fd0f4b..ea967ac 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1081,6 +1081,7 @@ "win/iat_patch_function.h", "win/iunknown_impl.cc", "win/iunknown_impl.h", + "win/map.h", "win/message_window.cc", "win/message_window.h", "win/object_watcher.cc", @@ -2814,6 +2815,7 @@ "win/hstring_reference_unittest.cc", "win/i18n_unittest.cc", "win/iunknown_impl_unittest.cc", + "win/map_unittest.cc", "win/message_window_unittest.cc", "win/object_watcher_unittest.cc", "win/pe_image_unittest.cc",
diff --git a/base/win/map.h b/base/win/map.h new file mode 100644 index 0000000..20ecc27 --- /dev/null +++ b/base/win/map.h
@@ -0,0 +1,424 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_MAP_H_ +#define BASE_WIN_MAP_H_ + +#include <windows.foundation.collections.h> +#include <wrl/implements.h> + +#include <map> + +#include "base/stl_util.h" +#include "base/win/vector.h" +#include "base/win/winrt_foundation_helpers.h" + +namespace base { +namespace win { + +template <typename K, typename V> +class Map; + +namespace internal { + +// Template tricks needed to dispatch to the correct implementation. +// See base/win/winrt_foundation_helpers.h for explanation. + +template <typename K, typename V> +using ComplexK = + typename ABI::Windows::Foundation::Collections::IMap<K, V>::K_complex; + +template <typename K, typename V> +using ComplexV = + typename ABI::Windows::Foundation::Collections::IMap<K, V>::V_complex; + +template <typename K, typename V> +using LogicalK = LogicalType<ComplexK<K, V>>; + +template <typename K, typename V> +using LogicalV = LogicalType<ComplexV<K, V>>; + +template <typename K, typename V> +using AbiK = AbiType<ComplexK<K, V>>; + +template <typename K, typename V> +using AbiV = AbiType<ComplexV<K, V>>; + +template <typename K, typename V> +using StorageK = StorageType<ComplexK<K, V>>; + +template <typename K, typename V> +using StorageV = StorageType<ComplexV<K, V>>; + +template <typename K, typename V> +class KeyValuePair : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::WinRtClassicComMix | + Microsoft::WRL::InhibitRoOriginateError>, + ABI::Windows::Foundation::Collections:: + IKeyValuePair<LogicalK<K, V>, LogicalV<K, V>>> { + public: + using AbiK = AbiK<K, V>; + using AbiV = AbiV<K, V>; + using StorageK = StorageK<K, V>; + using StorageV = StorageV<K, V>; + + KeyValuePair(StorageK key, StorageV value) + : key_(std::move(key)), value_(std::move(value)) {} + + // ABI::Windows::Foundation::Collections::IKeyValuePair: + IFACEMETHODIMP get_Key(AbiK* key) { return CopyTo(key_, key); } + + IFACEMETHODIMP get_Value(AbiV* value) { return CopyTo(value_, value); } + + private: + StorageK key_; + StorageV value_; +}; + +template <typename K> +class MapChangedEventArgs + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::WinRtClassicComMix | + Microsoft::WRL::InhibitRoOriginateError>, + ABI::Windows::Foundation::Collections::IMapChangedEventArgs<K>> { + public: + MapChangedEventArgs( + ABI::Windows::Foundation::Collections::CollectionChange change, + K key) + : change_(change), key_(std::move(key)) {} + + ~MapChangedEventArgs() override = default; + + // ABI::Windows::Foundation::Collections::IMapChangedEventArgs: + IFACEMETHODIMP get_CollectionChange( + ABI::Windows::Foundation::Collections::CollectionChange* value) override { + *value = change_; + return S_OK; + } + + IFACEMETHODIMP get_Key(K* value) override { + *value = key_; + return S_OK; + } + + private: + const ABI::Windows::Foundation::Collections::CollectionChange change_; + K key_; +}; + +} // namespace internal + +// This file provides an implementation of Windows::Foundation::IMap. It +// functions as a thin wrapper around an std::map, and dispatches +// method calls to either the corresponding std::map API or +// appropriate std algorithms. Furthermore, it notifies its observers whenever +// its observable state changes, and is iterable. Please notice also that if the +// map is modified while iterating over it, iterator methods will return +// E_CHANGED_STATE. A base::win::Map can be constructed for any types <K,V>, and +// is implicitly constructible from a std::map. In the case where K or V is a +// pointer derived from IUnknown, the std::map needs to be of type +// Microsoft::WRL::ComPtr<K> or Microsoft::WRL::ComPtr<V>. This enforces proper +// reference counting and improves safety. +template <typename K, typename V> +class Map + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, + ABI::Windows::Foundation::Collections::IMap<internal::LogicalK<K, V>, + internal::LogicalV<K, V>>, + ABI::Windows::Foundation::Collections::IObservableMap< + internal::LogicalK<K, V>, + internal::LogicalV<K, V>>, + ABI::Windows::Foundation::Collections::IIterable< + ABI::Windows::Foundation::Collections::IKeyValuePair< + internal::LogicalK<K, V>, + internal::LogicalV<K, V>>*>> { + public: + using LogicalK = internal::LogicalK<K, V>; + using LogicalV = internal::LogicalV<K, V>; + using AbiK = internal::AbiK<K, V>; + using AbiV = internal::AbiV<K, V>; + using StorageK = internal::StorageK<K, V>; + using StorageV = internal::StorageV<K, V>; + + private: + class MapView; + + // Iterates over base::win::Map. + // Its methods return E_CHANGED_STATE is the map is modified. + // TODO(https://crbug.com/987533): Refactor MapIterator to leverage + // std::map::iterator. + class MapIterator + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::WinRtClassicComMix | + Microsoft::WRL::InhibitRoOriginateError>, + ABI::Windows::Foundation::Collections::IIterator< + ABI::Windows::Foundation::Collections::IKeyValuePair< + internal::LogicalK<K, V>, + internal::LogicalV<K, V>>*>> { + public: + explicit MapIterator(Microsoft::WRL::ComPtr<MapView> view) + : view_(std::move(view)) { + DCHECK(view_->ValidState()); + ConvertMapToVectorIterator(); + } + + // ABI::Windows::Foundation::Collections::IIterator: + IFACEMETHODIMP get_Current( + ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK, + LogicalV>** + current) override { + return view_->ValidState() ? iterator_->get_Current(current) + : E_CHANGED_STATE; + } + + IFACEMETHODIMP get_HasCurrent(boolean* has_current) override { + return view_->ValidState() ? iterator_->get_HasCurrent(has_current) + : E_CHANGED_STATE; + } + + IFACEMETHODIMP MoveNext(boolean* has_current) override { + return view_->ValidState() ? iterator_->MoveNext(has_current) + : E_CHANGED_STATE; + } + + IFACEMETHODIMP GetMany( + unsigned capacity, + ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK, + LogicalV>** value, + unsigned* actual) override { + return view_->ValidState() ? iterator_->GetMany(capacity, value, actual) + : E_CHANGED_STATE; + } + + private: + // Helper for iteration: + void ConvertMapToVectorIterator() { + // Create a vector that will hold Map's key-value pairs. + auto vector = Microsoft::WRL::Make< + Vector<ABI::Windows::Foundation::Collections::IKeyValuePair< + LogicalK, LogicalV>*>>(); + + // Fill the vector with container data. + for (const auto& pair : view_->get_map()) { + auto key_value_pair = + Microsoft::WRL::Make<internal::KeyValuePair<AbiK, AbiV>>( + pair.first, pair.second); + vector->Append(key_value_pair.Get()); + } + + // Return an iterator to that vector. + // Iterator is immutable (wraps an IVectorView) and Vector's lifecycle is + // ensured cause the view holds a reference to the vector, and iterator + // holds a reference to the view. + HRESULT hr = vector->First(&iterator_); + DCHECK(SUCCEEDED(hr)); + } + + Microsoft::WRL::ComPtr<MapView> view_; + Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IIterator< + ABI::Windows::Foundation::Collections::IKeyValuePair<LogicalK, + LogicalV>*>> + iterator_; + }; + + class MapView + : public Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags< + Microsoft::WRL::WinRtClassicComMix | + Microsoft::WRL::InhibitRoOriginateError>, + ABI::Windows::Foundation::Collections:: + IMapView<internal::LogicalK<K, V>, internal::LogicalV<K, V>>, + ABI::Windows::Foundation::Collections::IIterable< + ABI::Windows::Foundation::Collections::IKeyValuePair< + internal::LogicalK<K, V>, + internal::LogicalV<K, V>>*>, + ABI::Windows::Foundation::Collections::MapChangedEventHandler< + internal::LogicalK<K, V>, + internal::LogicalV<K, V>>> { + public: + explicit MapView(Microsoft::WRL::ComPtr<Map<LogicalK, LogicalV>> map) + : map_(std::move(map)) { + map_->add_MapChanged(this, &map_changed_token_); + } + + ~MapView() { + if (map_) + map_->remove_MapChanged(map_changed_token_); + } + + // ABI::Windows::Foundation::Collections::IMapView: + IFACEMETHODIMP Lookup(AbiK key, AbiV* value) override { + return map_ ? map_->Lookup(key, value) : E_CHANGED_STATE; + } + + IFACEMETHODIMP get_Size(unsigned int* size) override { + return map_ ? map_->get_Size(size) : E_CHANGED_STATE; + } + + IFACEMETHODIMP HasKey(AbiK key, boolean* found) override { + return map_ ? map_->HasKey(key, found) : E_CHANGED_STATE; + } + + IFACEMETHODIMP Split( + ABI::Windows::Foundation::Collections::IMapView<LogicalK, LogicalV>** + first_partition, + ABI::Windows::Foundation::Collections::IMapView<LogicalK, LogicalV>** + second_partition) override { + NOTIMPLEMENTED(); + return E_NOTIMPL; + } + + // ABI::Windows::Foundation::Collections::IIterable: + IFACEMETHODIMP First(ABI::Windows::Foundation::Collections::IIterator< + ABI::Windows::Foundation::Collections:: + IKeyValuePair<LogicalK, LogicalV>*>** first) { + return map_ ? map_->First(first) : E_CHANGED_STATE; + } + + // ABI::Windows::Foundation::Collections::MapChangedEventHandler: + IFACEMETHODIMP Invoke( + ABI::Windows::Foundation::Collections::IObservableMap<LogicalK, + LogicalV>* sender, + ABI::Windows::Foundation::Collections::IMapChangedEventArgs<LogicalK>* + e) { + DCHECK_EQ(map_.Get(), sender); + map_.Reset(); + sender->remove_MapChanged(map_changed_token_); + return S_OK; + } + + // Accessor used in MapIterator for iterating over Map's container. + // Will remain valid during the entire iteration. + const std::map<StorageK, StorageV, internal::Less>& get_map() { + DCHECK(map_); + return map_->map_; + } + + bool ValidState() const { return map_; } + + private: + Microsoft::WRL::ComPtr<Map<LogicalK, LogicalV>> map_; + EventRegistrationToken map_changed_token_; + }; + + public: + Map() = default; + explicit Map(const std::map<StorageK, StorageV, internal::Less>& map) + : map_(map) {} + explicit Map(std::map<StorageK, StorageV, internal::Less>&& map) + : map_(std::move(map)) {} + + // ABI::Windows::Foundation::Collections::IMap: + IFACEMETHODIMP Lookup(AbiK key, AbiV* value) override { + auto it = map_.find(key); + if (it == map_.cend()) + return E_BOUNDS; + + return internal::CopyTo(it->second, value); + } + + IFACEMETHODIMP get_Size(unsigned int* size) override { + *size = map_.size(); + return S_OK; + } + + IFACEMETHODIMP HasKey(AbiK key, boolean* found) override { + *found = Contains(map_, key); + return S_OK; + } + + IFACEMETHODIMP GetView( + ABI::Windows::Foundation::Collections::IMapView<LogicalK, LogicalV>** + view) override { + return Microsoft::WRL::Make<MapView>(this).CopyTo(view); + } + + IFACEMETHODIMP Insert(AbiK key, AbiV value, boolean* replaced) override { + *replaced = !InsertOrAssign(map_, key, std::move(value)).second; + NotifyMapChanged(*replaced ? ABI::Windows::Foundation::Collections:: + CollectionChange_ItemChanged + : ABI::Windows::Foundation::Collections:: + CollectionChange_ItemInserted, + key); + return S_OK; + } + + IFACEMETHODIMP Remove(AbiK key) override { + if (!map_.erase(key)) + return E_BOUNDS; + + NotifyMapChanged( + ABI::Windows::Foundation::Collections::CollectionChange_ItemRemoved, + key); + return S_OK; + } + + IFACEMETHODIMP Clear() override { + map_.clear(); + NotifyMapChanged( + ABI::Windows::Foundation::Collections::CollectionChange_Reset, 0); + return S_OK; + } + + // ABI::Windows::Foundation::Collections::IObservableMap: + IFACEMETHODIMP add_MapChanged( + ABI::Windows::Foundation::Collections::MapChangedEventHandler<LogicalK, + LogicalV>* + handler, + EventRegistrationToken* token) override { + token->value = handler_id_++; + handlers_.emplace_hint(handlers_.end(), token->value, handler); + return S_OK; + } + + IFACEMETHODIMP remove_MapChanged(EventRegistrationToken token) override { + return handlers_.erase(token.value) ? S_OK : E_BOUNDS; + } + + // ABI::Windows::Foundation::Collections::IIterable: + IFACEMETHODIMP First(ABI::Windows::Foundation::Collections::IIterator< + ABI::Windows::Foundation::Collections:: + IKeyValuePair<LogicalK, LogicalV>*>** first) { + return Microsoft::WRL::Make<MapIterator>( + Microsoft::WRL::Make<MapView>(this)) + .CopyTo(first); + } + + private: + ~Map() override { + // Handlers should not outlive the Map. Furthermore, they must ensure + // they are unregistered before the the handler is destroyed. This implies + // there should be no handlers left when the Map is destructed. + DCHECK(handlers_.empty()); + } + + void NotifyMapChanged( + ABI::Windows::Foundation::Collections::CollectionChange change, + AbiK key) { + auto args = + Microsoft::WRL::Make<internal::MapChangedEventArgs<AbiK>>(change, key); + + // Invoking the handlers could result in mutations to the map, thus we make + // a copy beforehand. + auto handlers = handlers_; + for (auto& handler : handlers) + handler.second->Invoke(this, args.Get()); + } + + std::map<StorageK, StorageV, internal::Less> map_; + base::flat_map<int64_t, + ABI::Windows::Foundation::Collections:: + MapChangedEventHandler<LogicalK, LogicalV>*> + handlers_; + int64_t handler_id_ = 0; +}; + +} // namespace win +} // namespace base + +#endif // BASE_WIN_MAP_H_
diff --git a/base/win/map_unittest.cc b/base/win/map_unittest.cc new file mode 100644 index 0000000..096a55c --- /dev/null +++ b/base/win/map_unittest.cc
@@ -0,0 +1,548 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/map.h" + +#include <windows.foundation.h> + +#include "base/strings/utf_string_conversions.h" +#include "base/win/core_winrt_util.h" +#include "base/win/hstring_reference.h" +#include "base/win/scoped_hstring.h" +#include "base/win/windows_version.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace ABI { +namespace Windows { +namespace Foundation { +namespace Collections { + +// Add missing template specializations (since UWP doesn't provide them): + +// Map<int, double> specializations: +template <> +struct __declspec(uuid("34784dd6-b37b-4680-b391-899be4f755b6")) + IKeyValuePair<int, double> : IKeyValuePair_impl<int, double> {}; + +template <> +struct __declspec(uuid("c00bd9bd-cce5-46d6-9dc7-f03067e6d523")) + IMap<int, double> : IMap_impl<int, double> {}; + +template <> +struct __declspec(uuid("30e075af-9ba2-4562-9f10-a13a0e57ca5b")) + IMapView<int, double> : IMapView_impl<int, double> {}; + +template <> +struct __declspec(uuid("0a0e8ed6-7deb-4fd4-8033-38d270c69301")) + IObservableMap<int, double> : IObservableMap_impl<int, double> {}; + +template <> +struct __declspec(uuid("f41f9179-9c95-4755-af55-929a250fc0aa")) + IMapChangedEventArgs<int> : IMapChangedEventArgs_impl<int> {}; + +template <> +struct __declspec(uuid("79196029-07f6-47c6-9933-9ac3a04e7731")) + MapChangedEventHandler<int, double> + : MapChangedEventHandler_impl<int, double> {}; + +template <> +struct __declspec(uuid("bfd254c3-5ede-4f8f-9e48-3636347f6fe0")) + IIterable<IKeyValuePair<int, double>*> + : IIterable_impl<IKeyValuePair<int, double>*> {}; + +template <> +struct __declspec(uuid("6bb5c7ff-964e-469f-87d3-42daaea8e58d")) + IIterator<IKeyValuePair<int, double>*> + : IIterator_impl<IKeyValuePair<int, double>*> {}; + +template <> +struct __declspec(uuid("7d27014c-8df7-4977-bf98-b0c821f5f988")) + IVector<IKeyValuePair<int, double>*> + : IVector_impl<IKeyValuePair<int, double>*> {}; + +template <> +struct __declspec(uuid("d33b7a5c-9da6-4a6a-8b2e-e08cc0240d77")) + IVectorView<IKeyValuePair<int, double>*> + : IVectorView_impl<IKeyValuePair<int, double>*> {}; + +template <> +struct __declspec(uuid("e5b0d7f2-915d-4831-9a04-466fed63cfa0")) + VectorChangedEventHandler<IKeyValuePair<int, double>*> + : VectorChangedEventHandler_impl<IKeyValuePair<int, double>*> {}; + +template <> +struct __declspec(uuid("27c3ee04-457f-42dd-9556-8f7c4994d7af")) + IObservableVector<IKeyValuePair<int, double>*> + : IObservableVector_impl<IKeyValuePair<int, double>*> {}; + +// Map<Uri*, Uri*> specializations: +template <> +struct __declspec(uuid("c03984bc-b800-43e4-a36e-3c8c4a34c005")) IMap<Uri*, Uri*> + : IMap_impl<Uri*, Uri*> {}; + +template <> +struct __declspec(uuid("93ec9c52-1b0b-4fd8-ab5a-f6ea32db0e35")) + IMapView<Uri*, Uri*> : IMapView_impl<Uri*, Uri*> {}; + +template <> +struct __declspec(uuid("9b711c83-5f01-4604-9e01-3d586b3f9cdd")) + IObservableMap<Uri*, Uri*> : IObservableMap_impl<Uri*, Uri*> {}; + +template <> +struct __declspec(uuid("f41f9179-9c95-4755-af55-929a250fc0aa")) + IMapChangedEventArgs<Uri*> : IMapChangedEventArgs_impl<Uri*> {}; + +template <> +struct __declspec(uuid("6d758124-f99a-47e7-ab74-7cff7359b206")) + MapChangedEventHandler<Uri*, Uri*> + : MapChangedEventHandler_impl<Uri*, Uri*> {}; + +template <> +struct __declspec(uuid("8b270b8a-d74b-459b-9933-81cb234d7c5e")) + IKeyValuePair<Uri*, Uri*> : IKeyValuePair_impl<Uri*, Uri*> {}; + +template <> +struct __declspec(uuid("6368bcea-dfbc-4847-ba50-9e217fc2d5c3")) + IIterable<IKeyValuePair<Uri*, Uri*>*> + : IIterable_impl<IKeyValuePair<Uri*, Uri*>*> {}; + +template <> +struct __declspec(uuid("7653cf9f-9d0b-46d3-882e-4c0afb209333")) + IIterator<IKeyValuePair<Uri*, Uri*>*> + : IIterator_impl<IKeyValuePair<Uri*, Uri*>*> {}; + +template <> +struct __declspec(uuid("98c3f5a7-237d-494b-ba89-4a49368d5491")) + IVector<IKeyValuePair<Uri*, Uri*>*> + : IVector_impl<IKeyValuePair<Uri*, Uri*>*> {}; + +template <> +struct __declspec(uuid("2cfc2617-7c88-4482-8158-97bf7cc458d7")) + IVectorView<IKeyValuePair<Uri*, Uri*>*> + : IVectorView_impl<IKeyValuePair<Uri*, Uri*>*> {}; + +template <> +struct __declspec(uuid("bb581e03-3ee7-4c01-8035-4f581c5e91f5")) + VectorChangedEventHandler<IKeyValuePair<Uri*, Uri*>*> + : VectorChangedEventHandler_impl<IKeyValuePair<Uri*, Uri*>*> {}; + +template <> +struct __declspec(uuid("fb0bd692-34c3-4242-a085-58ed71e8ea6b")) + IObservableVector<IKeyValuePair<Uri*, Uri*>*> + : IObservableVector_impl<IKeyValuePair<Uri*, Uri*>*> {}; + +// Map<HSTRING*, IInspectable*> specializations: +template <> +struct __declspec(uuid("c6682be1-963c-4101-85aa-63db583eb0d5")) + IVector<IKeyValuePair<HSTRING, IInspectable*>*> + : IVector_impl<IKeyValuePair<HSTRING, IInspectable*>*> {}; + +template <> +struct __declspec(uuid("868e5342-49c8-478f-af0f-1691e1bbbb7c")) + IVectorView<IKeyValuePair<HSTRING, IInspectable*>*> + : IVectorView_impl<IKeyValuePair<HSTRING, IInspectable*>*> {}; + +template <> +struct __declspec(uuid("cd99b82f-a768-405f-9123-be509146fef8")) + VectorChangedEventHandler<IKeyValuePair<HSTRING, IInspectable*>*> + : VectorChangedEventHandler_impl<IKeyValuePair<HSTRING, IInspectable*>*> {}; + +template <> +struct __declspec(uuid("079e2180-0c7a-4508-85ff-7a5f2b29b92b")) + IObservableVector<IKeyValuePair<HSTRING, IInspectable*>*> + : IObservableVector_impl<IKeyValuePair<HSTRING, IInspectable*>*> {}; + +} // namespace Collections +} // namespace Foundation +} // namespace Windows +} // namespace ABI + +namespace base { +namespace win { + +namespace { + +using ABI::Windows::Foundation::IPropertyValue; +using ABI::Windows::Foundation::IPropertyValueStatics; +using ABI::Windows::Foundation::Uri; +using ABI::Windows::Foundation::Collections::CollectionChange; +using ABI::Windows::Foundation::Collections::CollectionChange_ItemChanged; +using ABI::Windows::Foundation::Collections::CollectionChange_ItemInserted; +using ABI::Windows::Foundation::Collections::CollectionChange_ItemRemoved; +using ABI::Windows::Foundation::Collections::CollectionChange_Reset; +using ABI::Windows::Foundation::Collections::IIterator; +using ABI::Windows::Foundation::Collections::IKeyValuePair; +using ABI::Windows::Foundation::Collections::IMapChangedEventArgs; +using ABI::Windows::Foundation::Collections::IMapView; +using ABI::Windows::Foundation::Collections::IObservableMap; +using ABI::Windows::Foundation::Collections::MapChangedEventHandler; +using Microsoft::WRL::ClassicCom; +using Microsoft::WRL::ComPtr; +using Microsoft::WRL::InhibitRoOriginateError; +using Microsoft::WRL::Make; +using Microsoft::WRL::RuntimeClass; +using Microsoft::WRL::RuntimeClassFlags; + +const wchar_t kTestKey[] = L"Test key"; +const wchar_t kTestValue[] = L"Test value"; + +const std::map<int, double, internal::Less> g_one{{1, 10.7}}; +const std::map<int, double, internal::Less> g_two{{1, 10.7}, {2, 20.3}}; + +bool ResolveCoreWinRT() { + return base::win::ResolveCoreWinRTDelayload() && + base::win::ScopedHString::ResolveCoreWinRTStringDelayload() && + base::win::HStringReference::ResolveCoreWinRTStringDelayload(); +} + +HRESULT GetPropertyValueStaticsActivationFactory( + IPropertyValueStatics** statics) { + return base::win::GetActivationFactory< + IPropertyValueStatics, RuntimeClass_Windows_Foundation_PropertyValue>( + statics); +} + +template <typename K, typename V> +class FakeMapChangedEventHandler + : public RuntimeClass< + RuntimeClassFlags<ClassicCom | InhibitRoOriginateError>, + MapChangedEventHandler<K, V>> { + public: + explicit FakeMapChangedEventHandler(ComPtr<IObservableMap<K, V>> map) + : map_(std::move(map)) { + EXPECT_HRESULT_SUCCEEDED(map_->add_MapChanged(this, &token_)); + } + + ~FakeMapChangedEventHandler() { + EXPECT_HRESULT_SUCCEEDED(map_->remove_MapChanged(token_)); + } + + // MapChangedEventHandler: + IFACEMETHODIMP Invoke(IObservableMap<K, V>* sender, + IMapChangedEventArgs<K>* e) { + sender_ = sender; + EXPECT_HRESULT_SUCCEEDED(e->get_CollectionChange(&change_)); + EXPECT_HRESULT_SUCCEEDED(e->get_Key(&key_)); + return S_OK; + } + + IObservableMap<K, V>* sender() { return sender_; } + CollectionChange change() { return change_; } + K key() const { return key_; } + + private: + ComPtr<IObservableMap<K, V>> map_; + EventRegistrationToken token_; + IObservableMap<K, V>* sender_ = nullptr; + CollectionChange change_ = CollectionChange_Reset; + K key_ = 0; +}; + +} // namespace + +TEST(MapTest, Lookup_Empty) { + auto map = Make<Map<int, double>>(); + double value; + HRESULT hr = map->Lookup(1, &value); + EXPECT_EQ(E_BOUNDS, hr); + hr = map->Lookup(2, &value); + EXPECT_EQ(E_BOUNDS, hr); +} + +TEST(MapTest, Lookup_One) { + auto map = Make<Map<int, double>>(g_one); + double value; + HRESULT hr = map->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(10.7, value); + hr = map->Lookup(2, &value); + EXPECT_EQ(E_BOUNDS, hr); +} + +TEST(MapTest, Lookup_Two) { + auto map = Make<Map<int, double>>(g_two); + double value; + HRESULT hr = map->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(10.7, value); + hr = map->Lookup(2, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(20.3, value); +} + +TEST(MapTest, get_Size_Empty) { + auto map = Make<Map<int, double>>(); + unsigned int size; + HRESULT hr = map->get_Size(&size); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(0u, size); +} + +TEST(MapTest, get_Size_One) { + auto map = Make<Map<int, double>>(g_one); + unsigned int size; + HRESULT hr = map->get_Size(&size); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(1u, size); +} + +TEST(MapTest, get_Size_Two) { + auto map = Make<Map<int, double>>(g_two); + unsigned int size; + HRESULT hr = map->get_Size(&size); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(2u, size); +} + +TEST(MapTest, HasKey_Empty) { + auto map = Make<Map<int, double>>(); + boolean found; + HRESULT hr = map->HasKey(1, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_FALSE(found); +} + +TEST(MapTest, HasKey_One) { + auto map = Make<Map<int, double>>(g_one); + boolean found; + HRESULT hr = map->HasKey(1, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(found); + hr = map->HasKey(2, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_FALSE(found); +} + +TEST(MapTest, HasKey_Two) { + auto map = Make<Map<int, double>>(g_two); + boolean found; + HRESULT hr = map->HasKey(1, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(found); + hr = map->HasKey(2, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(found); +} + +TEST(MapTest, GetView) { + auto map = Make<Map<int, double>>(g_two); + ComPtr<IMapView<int, double>> view; + HRESULT hr = map->GetView(&view); + EXPECT_HRESULT_SUCCEEDED(hr); + + double value; + hr = view->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(10.7, value); + hr = view->Lookup(2, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(20.3, value); + + unsigned int size; + hr = view->get_Size(&size); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(2u, size); + + boolean found; + hr = view->HasKey(1, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(found); + hr = view->HasKey(2, &found); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(found); + + // The view is supposed to be a snapshot of the map when it's created. + // Further modifications to the map will invalidate the view. + boolean replaced; + hr = map->Insert(3, 11.2, &replaced); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_FALSE(replaced); + + hr = view->Lookup(1, &value); + EXPECT_EQ(E_CHANGED_STATE, hr); + + hr = view->get_Size(&size); + EXPECT_EQ(E_CHANGED_STATE, hr); + + hr = view->HasKey(1, &found); + EXPECT_EQ(E_CHANGED_STATE, hr); +} + +TEST(MapTest, Insert_Empty) { + auto map = Make<Map<int, double>>(); + auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get()); + boolean replaced; + HRESULT hr = map->Insert(1, 11.2, &replaced); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_FALSE(replaced); + EXPECT_EQ(map.Get(), handler->sender()); + EXPECT_EQ(CollectionChange_ItemInserted, handler->change()); + EXPECT_EQ(1, handler->key()); + double value; + hr = map->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(11.2, value); +} + +TEST(MapTest, Insert_One) { + auto map = Make<Map<int, double>>(g_one); + auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get()); + double value; + HRESULT hr = map->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(10.7, value); + boolean replaced; + hr = map->Insert(1, 11.2, &replaced); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(replaced); + EXPECT_EQ(map.Get(), handler->sender()); + EXPECT_EQ(CollectionChange_ItemChanged, handler->change()); + EXPECT_EQ(1, handler->key()); + hr = map->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(11.2, value); +} + +TEST(MapTest, Remove_One) { + auto map = Make<Map<int, double>>(g_one); + auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get()); + double value; + HRESULT hr = map->Lookup(1, &value); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(10.7, value); + hr = map->Remove(1); + EXPECT_EQ(S_OK, hr); + EXPECT_EQ(map.Get(), handler->sender()); + EXPECT_EQ(CollectionChange_ItemRemoved, handler->change()); + EXPECT_EQ(1, handler->key()); + hr = map->Lookup(1, &value); + EXPECT_EQ(E_BOUNDS, hr); +} + +TEST(MapTest, Clear) { + auto map = Make<Map<int, double>>(g_one); + auto handler = Make<FakeMapChangedEventHandler<int, double>>(map.Get()); + HRESULT hr = map->Clear(); + EXPECT_EQ(map.Get(), handler->sender()); + EXPECT_EQ(CollectionChange_Reset, handler->change()); + EXPECT_EQ(0, handler->key()); + unsigned int size; + hr = map->get_Size(&size); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(0u, size); +} + +// Uri* is an AggregateType which ABI representation is IUriRuntimeClass*. +TEST(MapTest, ConstructWithAggregateTypes) { + auto map = Make<Map<Uri*, Uri*>>(); + unsigned size; + HRESULT hr = map->get_Size(&size); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(0u, size); +} + +TEST(MapTest, First) { + auto map = Make<Map<int, double>>(g_two); + ComPtr<IIterator<IKeyValuePair<int, double>*>> iterator; + + // Test iteration. + HRESULT hr = map->First(&iterator); + EXPECT_HRESULT_SUCCEEDED(hr); + boolean has_current; + hr = iterator->get_HasCurrent(&has_current); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(has_current); + ComPtr<IKeyValuePair<int, double>> current; + hr = iterator->get_Current(¤t); + EXPECT_HRESULT_SUCCEEDED(hr); + int key; + hr = current->get_Key(&key); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(1, key); + double value; + hr = current->get_Value(&value); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(10.7, value); + hr = iterator->MoveNext(&has_current); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(has_current); + hr = iterator->get_Current(¤t); + EXPECT_HRESULT_SUCCEEDED(hr); + hr = current->get_Key(&key); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(2, key); + hr = current->get_Value(&value); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_EQ(20.3, value); + hr = iterator->MoveNext(&has_current); + EXPECT_FALSE(SUCCEEDED(hr)); + EXPECT_EQ(E_BOUNDS, hr); + EXPECT_FALSE(has_current); + hr = iterator->get_Current(¤t); + EXPECT_FALSE(SUCCEEDED(hr)); + EXPECT_EQ(E_BOUNDS, hr); + + // Test invalidation. + hr = map->First(&iterator); + EXPECT_HRESULT_SUCCEEDED(hr); + hr = iterator->get_HasCurrent(&has_current); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_TRUE(has_current); + boolean replaced; + hr = map->Insert(3, 11.2, &replaced); + EXPECT_HRESULT_SUCCEEDED(hr); + EXPECT_FALSE(replaced); + hr = iterator->get_HasCurrent(&has_current); + EXPECT_EQ(E_CHANGED_STATE, hr); + hr = iterator->MoveNext(&has_current); + EXPECT_EQ(E_CHANGED_STATE, hr); +} + +TEST(MapTest, Properties) { + // This test case validates Map against Windows property key system, + // which is used to store WinRT device properties. + if (GetVersion() < Version::WIN8) + return; + + ASSERT_TRUE(ResolveCoreWinRT()); + ASSERT_HRESULT_SUCCEEDED(base::win::RoInitialize(RO_INIT_MULTITHREADED)); + + auto map = Make<Map<HSTRING, IInspectable*>>(); + + ComPtr<IPropertyValueStatics> property_value_statics; + HRESULT hr = + GetPropertyValueStaticsActivationFactory(&property_value_statics); + EXPECT_HRESULT_SUCCEEDED(hr); + + base::win::HStringReference value_stringref_inserted(kTestValue); + ComPtr<IPropertyValue> value_inserted; + hr = property_value_statics->CreateString(value_stringref_inserted.Get(), + &value_inserted); + EXPECT_HRESULT_SUCCEEDED(hr); + + base::win::HStringReference key_stringref_inserted(kTestKey); + boolean replaced; + hr = map->Insert(key_stringref_inserted.Get(), value_inserted.Get(), + &replaced); + EXPECT_HRESULT_SUCCEEDED(hr); + + base::win::HStringReference key_stringref_lookedup(kTestKey); + ComPtr<IInspectable> value_inspectable_lookedup; + hr = map->Lookup(key_stringref_lookedup.Get(), &value_inspectable_lookedup); + EXPECT_HRESULT_SUCCEEDED(hr); + + ComPtr<IPropertyValue> value_lookedup; + hr = value_inspectable_lookedup.As(&value_lookedup); + EXPECT_HRESULT_SUCCEEDED(hr); + + HSTRING value_string_lookedup; + hr = value_lookedup->GetString(&value_string_lookedup); + EXPECT_HRESULT_SUCCEEDED(hr); + + auto value_stringref_lookedup = ScopedHString(value_string_lookedup); + EXPECT_EQ(kTestValue, value_stringref_lookedup.Get()); +} + +} // namespace win +} // namespace base
diff --git a/build/android/gyp/native_libraries_template.py b/build/android/gyp/native_libraries_template.py index 901fd86..52ba0872 100644 --- a/build/android/gyp/native_libraries_template.py +++ b/build/android/gyp/native_libraries_template.py
@@ -24,7 +24,7 @@ // by LibraryLoader.java. // TODO(cjhopman): This is public since it is referenced by NativeTestActivity.java // directly. The two ways of library loading should be refactored into one. - public static {MAYBE_FINAL}String[] LIBRARIES = {LIBRARIES}; + public static {MAYBE_FINAL}String[] LIBRARIES = {{{LIBRARIES}}}; // This is the expected version of the 'main' native library, which is the one that // implements the initial set of base JNI functions including
diff --git a/build/android/gyp/write_native_libraries_java.py b/build/android/gyp/write_native_libraries_java.py index c7ad066..1bd542f 100755 --- a/build/android/gyp/write_native_libraries_java.py +++ b/build/android/gyp/write_native_libraries_java.py
@@ -32,9 +32,6 @@ parser.add_argument( '--native-libraries-list', help='File with list of native libraries.') parser.add_argument( - '--exclude-native-libraries', - help='List of native libraries to exclude from the output.') - parser.add_argument( '--version-number', default='""', help='Expected version of main library.') @@ -57,27 +54,16 @@ or not options.load_library_from_apk), ( 'Must set --enable-chromium-linker to load library from APK.') - lib_paths = [] - exclude_native_libraries = [] - if options.exclude_native_libraries: - exclude_native_libraries = options.exclude_native_libraries.split(',') + native_libraries_list = [] if options.native_libraries_list: with open(options.native_libraries_list) as f: - for line in f: - line = line.strip() - assert line.endswith('.so') - if os.path.basename(line) in exclude_native_libraries: - continue - lib_paths.append(line) - - def LibBasename(path): - filename = os.path.split(path)[1] - base = os.path.splitext(filename)[0] - return base[3:] # remove lib prefix - - # Convert to "base" library names: e.g. libfoo.so -> foo. - native_libraries_list = ( - '{%s}' % ','.join(['"%s"' % LibBasename(s) for s in lib_paths])) + for path in f: + path = path.strip() + filename = os.path.split(path)[1] + assert filename.startswith('lib') + assert filename.endswith('.so') + # Remove lib prefix and .so suffix. + native_libraries_list.append('"%s"' % filename[3:-3]) def bool_str(value): if value: @@ -91,7 +77,7 @@ 'USE_LINKER': bool_str(options.enable_chromium_linker), 'USE_LIBRARY_IN_ZIP_FILE': bool_str(options.load_library_from_apk), 'ENABLE_LINKER_TESTS': bool_str(options.enable_chromium_linker_tests), - 'LIBRARIES': native_libraries_list, + 'LIBRARIES': ','.join(native_libraries_list), 'VERSION_NUMBER': options.version_number, 'CPU_FAMILY': options.cpu_family, }
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 8b4192f0..363d0a5 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -728,8 +728,6 @@ # load_library_from_apk: (Optional) Whether libraries should be loaded from # the APK without uncompressing. # enable_chromium_linker_tests: (Optional) Whether to run tests. - # dont_load_shared_libraries: (Optional) List of native libraries to exclude - # from output. # use_final_fields: True to use final fields. When false, all other # variables must not be set. template("write_native_libraries_java") { @@ -787,12 +785,6 @@ invoker.enable_chromium_linker_tests) { args += [ "--enable-chromium-linker-tests" ] } - - # TODO(tiborg): Remove once all usages are removed. - if (defined(invoker.dont_load_shared_libraries)) { - args += [ "--exclude-native-libraries=" + - invoker.dont_load_shared_libraries ] - } } } } @@ -2655,7 +2647,6 @@ write_native_libraries_java("${_template_name}__native_libraries") { forward_variables_from(invoker, [ - "dont_load_shared_libraries", "enable_chromium_linker_tests", ]) deps = [ @@ -3365,7 +3356,6 @@ "dexlayout_profile", "disable_r8_outlining", "dist_ijar_path", - "dont_load_shared_libraries", "enable_chromium_linker_tests", "enable_multidex", "enable_native_mocks",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 99bd67e..abfd7312 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8905797561571658672 \ No newline at end of file +8905772899826882240 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 017dfd3..d31bc514 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8905797565613988256 \ No newline at end of file +8905773019186674272 \ No newline at end of file
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9a52a23..b3145e8 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -369,7 +369,6 @@ "//third_party/android_deps:javax_inject_javax_inject_java", "//third_party/android_media:android_media_java", "//third_party/android_sdk:android_gcm_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", "//third_party/android_swipe_refresh:android_swipe_refresh_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", @@ -377,6 +376,7 @@ "//third_party/cacheinvalidation:cacheinvalidation_javalib", "//third_party/cacheinvalidation:cacheinvalidation_proto_java", "//third_party/cct_dynamic_module:cct_dynamic_module_java", + "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/feed:feed_lib_proto_java", "//third_party/gif_player:gif_player_java", "//third_party/google_android_play_core:com_google_android_play_core_java", @@ -710,10 +710,10 @@ "//third_party/android_deps:com_android_support_mediarouter_v7_java", "//third_party/android_deps:com_android_support_recyclerview_v7_java", "//third_party/android_deps:com_android_support_support_annotations_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", "//third_party/cacheinvalidation:cacheinvalidation_javalib", + "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/hamcrest:hamcrest_java", "//ui/android:ui_java", "//url/mojom:url_mojom_gurl_java", @@ -755,7 +755,7 @@ "//third_party/android_deps:android_support_v4_java", "//third_party/android_media:android_media_resources", "//third_party/android_support_test_runner:runner_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", + "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/espresso:espresso_all_java", "//third_party/junit:junit", ] @@ -862,13 +862,13 @@ "//third_party/android_sdk:android_test_runner_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", "//third_party/blink/public:blink_headers_java", "//third_party/blink/public/mojom:android_mojo_bindings_java", "//third_party/blink/public/mojom:mojom_mhtml_load_result_java", "//third_party/blink/public/mojom:mojom_platform_java", "//third_party/cacheinvalidation:cacheinvalidation_javalib", "//third_party/cct_dynamic_module:cct_dynamic_module_java", + "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/espresso:espresso_all_java", "//third_party/hamcrest:hamcrest_java", "//third_party/jsr-305:jsr_305_javalib", @@ -950,13 +950,13 @@ "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", "//net/android:net_java_test_support", - "//third_party/android_deps:android_arch_lifecycle_common_java", - "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:com_android_support_recyclerview_v7_java", - "//third_party/android_deps:com_android_support_support_annotations_java", "//third_party/android_support_test_runner:rules_java", "//third_party/android_support_test_runner:runner_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", + "//third_party/android_deps:android_arch_lifecycle_common_java", + "//third_party/android_deps:com_android_support_support_annotations_java", + "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:com_android_support_recyclerview_v7_java", + "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/junit", "//third_party/ub-uiautomator:ub_uiautomator_java", "//ui/android:ui_java",
diff --git a/chrome/android/features/start_surface/internal/BUILD.gn b/chrome/android/features/start_surface/internal/BUILD.gn index 0d9a901..9a3863d1 100644 --- a/chrome/android/features/start_surface/internal/BUILD.gn +++ b/chrome/android/features/start_surface/internal/BUILD.gn
@@ -108,7 +108,7 @@ deps += [ "//chrome/android/public/profiles:java", "//content/public/android:content_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", + "//third_party/custom_tabs_client:custom_tabs_support_java", "//third_party/feed:feed_lib_java", "//ui/android:ui_utils_java", "//ui/base/mojom:mojom_java",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceNavigationDelegate.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceNavigationDelegate.java index 8de5396b..9675009 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceNavigationDelegate.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceNavigationDelegate.java
@@ -8,6 +8,7 @@ import android.net.Uri; import android.provider.Browser; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate; @@ -16,8 +17,6 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.mojom.WindowOpenDisposition; -import androidx.browser.customtabs.CustomTabsIntent; - /** Implementation of the {@link NativePageNavigationDelegate} for the explore surface. */ class ExploreSurfaceNavigationDelegate implements NativePageNavigationDelegate { private final Context mContext; @@ -57,4 +56,4 @@ public void setIncognito(boolean isIncognito) { mIsInCognito = isIncognito; } -} +} \ No newline at end of file
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentStorageDirect.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentStorageDirect.java new file mode 100644 index 0000000..0f65da1 --- /dev/null +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentStorageDirect.java
@@ -0,0 +1,55 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import com.google.android.libraries.feed.api.host.storage.CommitResult; +import com.google.android.libraries.feed.api.host.storage.ContentMutation; +import com.google.android.libraries.feed.api.host.storage.ContentStorage; +import com.google.android.libraries.feed.api.host.storage.ContentStorageDirect; +import com.google.android.libraries.feed.common.Result; + +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Wrapper around {@link ContentStorage}, providing a synchronous implementation. + */ +public final class FeedContentStorageDirect implements ContentStorageDirect { + private static final String LOCATION = "FeedContentStorageDirect."; + private final ContentStorage mContentStorage; + + FeedContentStorageDirect(ContentStorage contentStorage) { + mContentStorage = contentStorage; + } + + @Override + public Result<Map<String, byte[]>> get(List<String> keys) { + if (keys.isEmpty()) { + return Result.success(Collections.emptyMap()); + } + + return FutureTaskConsumer.consume(LOCATION + "get", + (consumer) -> mContentStorage.get(keys, consumer), Result.failure()); + } + + @Override + public Result<Map<String, byte[]>> getAll(String prefix) { + return FutureTaskConsumer.consume(LOCATION + "getAll", + (consumer) -> mContentStorage.getAll(prefix, consumer), Result.failure()); + } + + @Override + public CommitResult commit(ContentMutation mutation) { + return FutureTaskConsumer.consume(LOCATION + "commit", + (consumer) -> mContentStorage.commit(mutation, consumer), CommitResult.FAILURE); + } + + @Override + public Result<List<String>> getAllKeys() { + return FutureTaskConsumer.consume( + LOCATION + "getAllKeys", mContentStorage::getAllKeys, Result.failure()); + } +}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalStorageDirect.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalStorageDirect.java new file mode 100644 index 0000000..8417c79 --- /dev/null +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalStorageDirect.java
@@ -0,0 +1,55 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import com.google.android.libraries.feed.api.host.storage.CommitResult; +import com.google.android.libraries.feed.api.host.storage.JournalMutation; +import com.google.android.libraries.feed.api.host.storage.JournalStorage; +import com.google.android.libraries.feed.api.host.storage.JournalStorageDirect; +import com.google.android.libraries.feed.common.Result; + +import java.util.List; + +/** + * Wrapper around {@link JournalStorage}, providing a synchronous implementation. + */ +public final class FeedJournalStorageDirect implements JournalStorageDirect { + private static final String LOCATION = "FeedJournalStorageDirect."; + private final JournalStorage mJournalStorage; + + FeedJournalStorageDirect(JournalStorage journalStorage) { + this.mJournalStorage = journalStorage; + } + + @Override + public Result<List<byte[]>> read(String journalName) { + return FutureTaskConsumer.consume(LOCATION + "read", + (consumer) -> mJournalStorage.read(journalName, consumer), Result.failure()); + } + + @Override + public CommitResult commit(JournalMutation mutation) { + return FutureTaskConsumer.consume(LOCATION + "commit", + (consumer) -> mJournalStorage.commit(mutation, consumer), CommitResult.FAILURE); + } + + @Override + public Result<Boolean> exists(String journalName) { + return FutureTaskConsumer.consume(LOCATION + "exists", + (consumer) -> mJournalStorage.exists(journalName, consumer), Result.failure()); + } + + @Override + public Result<List<String>> getAllJournals() { + return FutureTaskConsumer.consume( + LOCATION + "getAllJournals", mJournalStorage::getAllJournals, Result.failure()); + } + + @Override + public CommitResult deleteAll() { + return FutureTaskConsumer.consume( + LOCATION + "deleteAll", mJournalStorage::deleteAll, CommitResult.FAILURE); + } +}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java index 57894f3..4dbc8316 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedProcessScopeFactory.java
@@ -150,8 +150,10 @@ FeedSchedulerBridge schedulerBridge = new FeedSchedulerBridge(profile); sFeedScheduler = schedulerBridge; - FeedContentStorage contentStorage = new FeedContentStorage(profile); - FeedJournalStorage journalStorage = new FeedJournalStorage(profile); + ContentStorageDirect contentStorageDirect = + new FeedContentStorageDirect(new FeedContentStorage(profile)); + JournalStorageDirect journalStorageDirect = + new FeedJournalStorageDirect(new FeedJournalStorage(profile)); NetworkClient networkClient = sTestNetworkClient == null ? new FeedNetworkBridge(profile) : sTestNetworkClient; sFeedLoggingBridge = new FeedLoggingBridge(profile); @@ -159,8 +161,8 @@ sFeedLoggingBridge, networkClient, schedulerBridge, DebugBehavior.SILENT, ContextUtils.getApplicationContext(), applicationInfo, new BasicTooltipSupportedApi()) - .setContentStorage(contentStorage) - .setJournalStorage(journalStorage) + .setContentStorageDirect(contentStorageDirect) + .setJournalStorageDirect(journalStorageDirect) .build(); schedulerBridge.initializeFeedDependencies(sProcessScope.getRequestManager());
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FutureTaskConsumer.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FutureTaskConsumer.java new file mode 100644 index 0000000..b87bf77 --- /dev/null +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FutureTaskConsumer.java
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import com.google.android.libraries.feed.common.concurrent.SimpleSettableFuture; +import com.google.android.libraries.feed.common.functional.Consumer; + +import org.chromium.base.Callback; +import org.chromium.base.Log; + +import java.util.concurrent.ExecutionException; + +/** + * Processes a {@link Callback} on a {@link SimpleSettableFuture}. This is necessary to provide a + * synchronous interface to the Feed consumer. + */ +public class FutureTaskConsumer { + private static final String TAG = "FutureTaskConsumer"; + /** + * Sets the task result on a Future and returns it. + * + * @param location Caller location for error logging. + * @param task Callback on which to run the results. + * @param failure Default result in case of failure. + * @param <T> Type of result expected by the Feed {@link Consumer}. + * @return Result of the task. + */ + public static <T> T consume(String location, Callback<Consumer<T>> task, T failure) { + SimpleSettableFuture<T> sharedStatesFuture = new SimpleSettableFuture<>(); + task.onResult(sharedStatesFuture::put); + try { + return sharedStatesFuture.get(); + } catch (InterruptedException | ExecutionException e) { + Log.e(TAG, "%s: %s", location, e.toString()); + return failure; + } + } +}
diff --git a/chrome/android/feed/feed_java_sources.gni b/chrome/android/feed/feed_java_sources.gni index 182d4a1..f4645951 100644 --- a/chrome/android/feed/feed_java_sources.gni +++ b/chrome/android/feed/feed_java_sources.gni
@@ -14,9 +14,11 @@ "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedConfiguration.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentStorage.java", + "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedContentStorageDirect.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedImageLoader.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalStorage.java", + "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedJournalStorageDirect.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLifecycleBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedLoggingBridge.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNetworkBridge.java", @@ -30,6 +32,7 @@ "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedRefreshTask.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedScheduler.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSchedulerBridge.java", + "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FutureTaskConsumer.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java", "//chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/TestNetworkClient.java", @@ -47,6 +50,7 @@ "junit/src/org/chromium/chrome/browser/feed/FeedImageLoaderTest.java", "junit/src/org/chromium/chrome/browser/feed/FeedJournalStorageTest.java", "junit/src/org/chromium/chrome/browser/feed/FeedOfflineBridgeTest.java", + "junit/src/org/chromium/chrome/browser/feed/FutureTaskConsumerTest.java", "junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java", "junit/src/org/chromium/chrome/browser/feed/action/FeedActionHandlerTest.java", ]
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 22591d1..545468e1 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -1169,7 +1169,7 @@ <category android:name="androidx.browser.customtabs.category.ColorSchemeCustomization"/> </intent-filter> </service> - <service android:name="androidx.browser.customtabs.PostMessageService" /> + <service android:name="android.support.customtabs.PostMessageService" /> <!-- Crash reporting services. --> <service android:name="org.chromium.chrome.browser.crash.ChromeMinidumpUploadJobService"
diff --git a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected index 7c4c3c4..337c7b9 100644 --- a/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected +++ b/chrome/android/java/monochrome_public_bundle__base_bundle_module.AndroidManifest.expected
@@ -1578,7 +1578,7 @@ <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/> </intent-filter> </service> - <service android:name="androidx.browser.customtabs.PostMessageService"/> + <service android:name="android.support.customtabs.PostMessageService"/> <service android:exported="true" android:externalService="true"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 6d74dd5c..ea03517 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1054,10 +1054,7 @@ private void setInitialOverviewState() { boolean isOverviewVisible = mOverviewModeController.overviewVisible(); - // Experiment: show tab switcher on return after {x} minutes (enable-tab-switcher-on-return} - long lastBackgroundedTimeMillis = mInactivityTracker.getLastBackgroundedTimeMs(); - if (ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(lastBackgroundedTimeMillis) - && isMainIntentFromLauncher(getIntent()) && !isOverviewVisible) { + if (shouldShowTabSwitcherOnStart() && !isOverviewVisible) { if (getCurrentTabModel() != null) { RecordHistogram.recordCountHistogram( TAB_COUNT_ON_RETURN, getCurrentTabModel().getCount()); @@ -1071,6 +1068,12 @@ } } + private boolean shouldShowTabSwitcherOnStart() { + long lastBackgroundedTimeMillis = mInactivityTracker.getLastBackgroundedTimeMs(); + return ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(lastBackgroundedTimeMillis) + && isMainIntentFromLauncher(getIntent()); + } + private boolean isMainIntentFromLauncher(Intent intent) { return intent != null && TextUtils.equals(intent.getAction(), Intent.ACTION_MAIN) && intent.hasCategory(Intent.CATEGORY_LAUNCHER); @@ -1252,6 +1255,10 @@ * Create an initial tab for cold start without restored tabs. */ private void createInitialTab() { + // If the grid tab switcher is enabled and the tab switcher will be shown on start, + // do not create a new tab. With the grid, creating a new tab is now a one tap action. + if (shouldShowTabSwitcherOnStart() && FeatureUtilities.isGridTabSwitcherEnabled()) return; + String url = HomepageManager.getHomepageUri(); if (TextUtils.isEmpty(url)) { url = UrlConstants.NTP_URL;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java index c0a4746..d0916c7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -16,6 +16,9 @@ import android.os.Bundle; import android.os.StrictMode; import android.support.annotation.IntDef; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.TrustedWebUtils; import org.chromium.base.ApplicationStatus; import org.chromium.base.CommandLine; @@ -54,10 +57,6 @@ import java.lang.annotation.RetentionPolicy; import java.util.UUID; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.TrustedWebUtils; - /** * Dispatches incoming intents to the appropriate activity based on the current configuration and * Intent fired.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java index 70985ed..e24e9a9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java
@@ -11,6 +11,7 @@ import android.net.Uri; import android.provider.Browser; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; @@ -40,8 +41,6 @@ import java.util.List; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Tab Launcher to be used to launch new tabs from background Android Services, * when it is not known whether an activity is available. It will send an intent to launch the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/BrowserSessionDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/BrowserSessionDataProvider.java index 57ccd40..c1e0f06 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/BrowserSessionDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/BrowserSessionDataProvider.java
@@ -9,13 +9,12 @@ import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsSessionToken; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.util.IntentUtils; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * A model class that parses intent from third-party apps for data related with various browser * services related Intent types.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java index 0abfec2c..505d60f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java
@@ -5,6 +5,9 @@ package org.chromium.chrome.browser.browserservices; import android.os.Bundle; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.TrustedWebUtils; import android.support.v7.app.AppCompatActivity; import org.chromium.base.Log; @@ -15,10 +18,6 @@ import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.website.SettingsNavigationSource; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.TrustedWebUtils; - /** * Launched by {@link android.support.customtabs.TrustedWebUtils#launchBrowserSiteSettings}. * Verifies that url provided in intent has valid Digital Asset Link with the calling application,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java index 460629d..741695f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java
@@ -11,6 +11,8 @@ import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsService.Relation; import android.text.TextUtils; import org.chromium.base.CommandLine; @@ -46,8 +48,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsService.Relation; import dagger.Reusable; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java index 5027891..e860b0a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java
@@ -5,6 +5,9 @@ package org.chromium.chrome.browser.browserservices; import android.net.Uri; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.PostMessageBackend; import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; @@ -18,10 +21,6 @@ import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContentsObserver; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.PostMessageBackend; - /** * A class that handles postMessage communications with a designated {@link CustomTabsSessionToken}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java index 7bffd3b..d819ca9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionDataHolder.java
@@ -10,6 +10,7 @@ import android.net.Uri; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsSessionToken; import android.util.SparseArray; import org.chromium.base.Callback; @@ -18,8 +19,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import androidx.browser.customtabs.CustomTabsSessionToken; - import dagger.Lazy; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionHandler.java index 6745237..fcc8cc95 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/SessionHandler.java
@@ -10,10 +10,9 @@ import android.graphics.Bitmap; import android.net.Uri; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsSessionToken; import android.widget.RemoteViews; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Interface to handle browser services calls whenever the session id matched. * TODO(yusufo): Add a way to handle mayLaunchUrl as well.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java index 3f04db4..7e88948 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClient.java
@@ -17,6 +17,9 @@ import android.net.Uri; import android.os.RemoteException; import android.support.annotation.Nullable; +import android.support.customtabs.trusted.TrustedWebActivityService; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; +import android.support.customtabs.trusted.TrustedWebActivityServiceWrapper; import org.chromium.base.ContextUtils; import org.chromium.chrome.R; @@ -34,10 +37,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import androidx.browser.trusted.TrustedWebActivityService; -import androidx.browser.trusted.TrustedWebActivityServiceConnectionManager; -import androidx.browser.trusted.TrustedWebActivityServiceWrapper; - /** * Uses a Trusted Web Activity client to display notifications. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java index 3b0db84..ae8dfae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/controller/TrustedWebActivityVerifier.java
@@ -8,6 +8,7 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsService; import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; @@ -40,7 +41,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.CustomTabsService; import dagger.Lazy; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/SplashImageHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/SplashImageHolder.java index d774c520..82da66ea 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/SplashImageHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/SplashImageHolder.java
@@ -6,6 +6,7 @@ import android.graphics.Bitmap; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsSessionToken; import android.util.ArrayMap; import java.util.Collections; @@ -14,8 +15,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Stores the splash images received from TWA clients between the call to * {@link android.support.customtabs.CustomTabsService#receiveFile} and a Trusted Web Activity
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java index 3847f8b1..3472d63 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/splashscreen/TwaSplashController.java
@@ -13,6 +13,8 @@ import android.graphics.Matrix; import android.os.Build; import android.os.Bundle; +import android.support.customtabs.TrustedWebUtils; +import android.support.customtabs.TrustedWebUtils.SplashScreenParamKey; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -32,9 +34,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.TrustedWebUtils; -import androidx.browser.customtabs.TrustedWebUtils.SplashScreenParamKey; - /** * Orchestrates the flow of showing and removing splash screens for apps based on Trusted Web * Activities.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java index 630833556..6b57a5f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/ClientManager.java
@@ -15,6 +15,11 @@ import android.os.SystemClock; import android.support.annotation.IntDef; import android.support.annotation.NonNull; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsService.Relation; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.PostMessageServiceConnection; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.SparseBooleanArray; @@ -45,12 +50,6 @@ import java.util.Map; import java.util.Set; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsService.Relation; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.PostMessageServiceConnection; - /** Manages the clients' state for Custom Tabs. This class is threadsafe. */ class ClientManager { // Values for the "CustomTabs.MayLaunchUrlType" UMA histogram. Append-only.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java index 1362ef9..8970624 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomButtonParams.java
@@ -13,6 +13,7 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; import android.view.Gravity; import android.view.LayoutInflater; @@ -34,8 +35,6 @@ import java.util.List; import java.util.Set; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Container for all parameters related to creating a customizable button. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 4cbb26c..b8aed09 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -4,10 +4,10 @@ package org.chromium.chrome.browser.customtabs; -import static org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason.USER_NAVIGATION; +import static android.support.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK; +import static android.support.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT; -import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK; -import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT; +import static org.chromium.chrome.browser.customtabs.content.CustomTabActivityNavigationController.FinishReason.USER_NAVIGATION; import android.app.Activity; import android.app.PendingIntent; @@ -24,6 +24,9 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; import android.text.TextUtils; import android.util.Pair; import android.view.KeyEvent; @@ -87,10 +90,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * The activity for custom tabs. It will be launched on top of a client's task. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java index 7d532c91..a280b952 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabBottomBarDelegate.java
@@ -9,6 +9,7 @@ import android.content.Intent; import android.net.Uri; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; @@ -36,8 +37,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Delegate that manages bottom bar area inside of {@link CustomTabActivity}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index cb865b5..f9c287b3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -4,8 +4,8 @@ package org.chromium.chrome.browser.customtabs; -import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT; -import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_SYSTEM; +import static android.support.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT; +import static android.support.customtabs.CustomTabsIntent.COLOR_SCHEME_SYSTEM; import android.app.PendingIntent; import android.app.PendingIntent.CanceledException; @@ -21,6 +21,10 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabColorSchemeParams; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.TrustedWebUtils; import android.text.TextUtils; import android.util.Pair; import android.view.View; @@ -52,11 +56,6 @@ import java.util.List; import java.util.regex.Pattern; -import androidx.browser.customtabs.CustomTabColorSchemeParams; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.TrustedWebUtils; - /** * A model class that parses the incoming intent for Custom Tabs specific customization data. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java index e564da8..b4e249a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java
@@ -4,6 +4,9 @@ package org.chromium.chrome.browser.customtabs; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsSessionToken; + import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -13,9 +16,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * An observer for firing navigation events on {@link CustomTabsCallback}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java index f7e9540c..7e97613 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java
@@ -6,6 +6,7 @@ import android.content.Intent; import android.support.annotation.NonNull; +import android.support.customtabs.CustomTabsIntent; import android.support.v7.app.AppCompatDelegate; import org.chromium.base.ObserverList; @@ -17,8 +18,6 @@ import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.browser.util.IntentUtils; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Maintains and provides the night mode state for {@link CustomTabActivity}. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java index 0c25cc3..a8224ac 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java
@@ -11,6 +11,7 @@ import android.net.Uri; import android.os.SystemClock; import android.support.annotation.IntDef; +import android.support.customtabs.CustomTabsSessionToken; import android.text.TextUtils; import android.text.format.DateUtils; @@ -33,8 +34,6 @@ import javax.inject.Inject; import javax.inject.Named; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * A {@link TabObserver} that also handles custom tabs specific logging and messaging. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsClientFileProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsClientFileProcessor.java index dacb04b0..c22ff34c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsClientFileProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsClientFileProcessor.java
@@ -11,6 +11,8 @@ import android.net.Uri; import android.os.Bundle; import android.support.annotation.WorkerThread; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; import org.chromium.base.FileUtils; import org.chromium.base.Log; @@ -20,8 +22,6 @@ import javax.inject.Named; import javax.inject.Singleton; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; import dagger.Lazy; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index ae1c4ea..2c602ec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -19,6 +19,11 @@ import android.os.SystemClock; import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.PostMessageServiceConnection; import android.text.TextUtils; import android.widget.RemoteViews; @@ -84,12 +89,6 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.PostMessageServiceConnection; - /** * Implementation of the ICustomTabsService interface. * @@ -345,11 +344,7 @@ .onSessionDisconnected(session); } }; - - // TODO(peconn): Make this not an anonymous class once PostMessageServiceConnection is made - // non-abstract in AndroidX. - PostMessageServiceConnection serviceConnection = - new PostMessageServiceConnection(session) {}; + PostMessageServiceConnection serviceConnection = new PostMessageServiceConnection(session); PostMessageHandler handler = new PostMessageHandler(serviceConnection); return mClientManager.newSession( session, Binder.getCallingUid(), onDisconnect, handler, serviceConnection);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java index bfba782e..028c4ba 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionService.java
@@ -10,6 +10,8 @@ import android.os.IBinder; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.browserservices.Origin; @@ -18,9 +20,6 @@ import java.util.List; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Custom tabs connection service, used by the embedded Chrome activities. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/HiddenTabHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/HiddenTabHolder.java index 730e0cfac..fb75a3fa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/HiddenTabHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/HiddenTabHolder.java
@@ -9,6 +9,7 @@ import android.graphics.Rect; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsSessionToken; import android.text.TextUtils; import org.chromium.base.ContextUtils; @@ -27,8 +28,6 @@ import org.chromium.network.mojom.ReferrerPolicy; import org.chromium.ui.base.WindowAndroid; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Holds a hidden tab which may be used to preload pages before a CustomTabActivity is launched. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java index 1301ff5..8fa4dee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/PageLoadMetricsObserver.java
@@ -5,14 +5,13 @@ package org.chromium.chrome.browser.customtabs; import android.os.Bundle; +import android.support.customtabs.CustomTabsSessionToken; import org.chromium.chrome.browser.metrics.PageLoadMetrics; import org.chromium.chrome.browser.net.spdyproxy.DataReductionProxySettings; import org.chromium.chrome.browser.tab.Tab; import org.chromium.content_public.browser.WebContents; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Notifies the provided {@link CustomTabsConnection} of page load metrics, such as time until first * contentful paint.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java index 477747d..8caf375 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityTabController.java
@@ -10,6 +10,7 @@ import android.provider.Browser; import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsSessionToken; import android.text.TextUtils; import android.view.Window; @@ -55,7 +56,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.CustomTabsSessionToken; import dagger.Lazy; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabIntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabIntentHandler.java index 56842ab..05ba38c2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabIntentHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/content/CustomTabIntentHandler.java
@@ -10,6 +10,7 @@ import android.content.Intent; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsSessionToken; import org.chromium.chrome.browser.customtabs.CustomTabIntentDataProvider; import org.chromium.chrome.browser.dependency_injection.ActivityScope; @@ -18,8 +19,6 @@ import javax.inject.Inject; import javax.inject.Named; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Handles the incoming intents: the one that starts the activity, as well as subsequent intents * received in onNewIntent.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegatePostMessageBackend.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegatePostMessageBackend.java index 435fec3..4a3be88 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegatePostMessageBackend.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ActivityDelegatePostMessageBackend.java
@@ -6,8 +6,7 @@ import android.content.Context; import android.os.Bundle; - -import androidx.browser.customtabs.PostMessageBackend; +import android.support.customtabs.PostMessageBackend; /** * A {@link PostMessageBackend} which delegates incoming notifications to the {@link
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java index f4b2453d..dd0cf78 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java
@@ -11,6 +11,8 @@ import android.net.Uri; import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.PostMessageBackend; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; @@ -53,8 +55,6 @@ import javax.inject.Inject; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.PostMessageBackend; import dagger.Lazy; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java index aa07693b..ecaf288 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleNavigationEventObserver.java
@@ -4,16 +4,17 @@ package org.chromium.chrome.browser.customtabs.dynamicmodule; -import static androidx.browser.customtabs.CustomTabsCallback.NAVIGATION_FAILED; -import static androidx.browser.customtabs.CustomTabsCallback.NAVIGATION_FINISHED; -import static androidx.browser.customtabs.CustomTabsCallback.NAVIGATION_STARTED; -import static androidx.browser.customtabs.CustomTabsCallback.TAB_HIDDEN; -import static androidx.browser.customtabs.CustomTabsCallback.TAB_SHOWN; +import static android.support.customtabs.CustomTabsCallback.NAVIGATION_FAILED; +import static android.support.customtabs.CustomTabsCallback.NAVIGATION_FINISHED; +import static android.support.customtabs.CustomTabsCallback.NAVIGATION_STARTED; +import static android.support.customtabs.CustomTabsCallback.TAB_HIDDEN; +import static android.support.customtabs.CustomTabsCallback.TAB_SHOWN; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsCallback; import android.text.TextUtils; import org.chromium.base.VisibleForTesting; @@ -27,8 +28,6 @@ import java.util.ArrayList; import java.util.List; -import androidx.browser.customtabs.CustomTabsCallback; - /** * An observer for firing navigation events to the CCT dynamic module. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java index eb98eff9..deb2a5e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbarCoordinator.java
@@ -7,6 +7,7 @@ import static org.chromium.chrome.browser.dependency_injection.ChromeCommonQualifiers.APP_CONTEXT; import android.content.Context; +import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; import android.view.View; @@ -38,7 +39,6 @@ import javax.inject.Inject; import javax.inject.Named; -import androidx.browser.customtabs.CustomTabsIntent; import dagger.Lazy; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java index 3cd42a5..76cf447f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppModule.java
@@ -8,6 +8,7 @@ import static org.chromium.chrome.browser.dependency_injection.ChromeCommonQualifiers.LAST_USED_PROFILE; import android.content.Context; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.WarmupManager; @@ -22,7 +23,6 @@ import javax.inject.Named; import javax.inject.Singleton; -import androidx.browser.trusted.TrustedWebActivityServiceConnectionManager; import dagger.Module; import dagger.Provides;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java index 75e9ecb..66a1d84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeManager.java
@@ -8,6 +8,7 @@ import android.content.Intent; import android.net.Uri; import android.support.annotation.NonNull; +import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; import org.chromium.base.CommandLine; @@ -43,8 +44,6 @@ import java.util.HashMap; import java.util.Map; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Manages UI effects for reader mode including hiding and showing the * reader mode and reader mode preferences toolbar icon and hiding the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java index 7fcad25..a6662256 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
@@ -11,12 +11,14 @@ import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.sync.SyncAndServicesPreferences; import org.chromium.chrome.browser.signin.IdentityServicesProvider; import org.chromium.chrome.browser.signin.SigninManager; import org.chromium.chrome.browser.signin.SigninManager.SignInCallback; import org.chromium.chrome.browser.signin.UnifiedConsentServiceBridge; +import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.util.FeatureUtilities; /** @@ -79,6 +81,9 @@ // Show sync settings if user pressed the "Settings" button. if (setUp) { openSignInSettings(activity); + } else if (ChromeFeatureList.isEnabled( + ChromeFeatureList.SYNC_MANUAL_START_ANDROID)) { + ProfileSyncService.get().setFirstSetupComplete(); } setFirstRunFlowSignInComplete(true); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java index dae6e65a..1a7c05a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/MediaViewerUtils.java
@@ -17,6 +17,7 @@ import android.net.Uri; import android.os.Build; import android.provider.Browser; +import android.support.customtabs.CustomTabsIntent; import android.text.TextUtils; import org.chromium.base.ApiCompatibilityUtils; @@ -32,8 +33,6 @@ import java.util.Locale; -import androidx.browser.customtabs.CustomTabsIntent; - /** * A class containing some utility static methods. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java index 0c8c0245..824c255 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java
@@ -10,6 +10,7 @@ import android.content.Intent; import android.net.Uri; import android.provider.Browser; +import android.support.customtabs.CustomTabsIntent; import org.chromium.base.ApplicationStatus; import org.chromium.base.ContextUtils; @@ -40,8 +41,6 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.widget.Toast; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Serves as an interface between Download Home UI and offline page related items that are to be * displayed in the downloads UI.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java index 2f7bf40..cc6e303 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessor.java
@@ -131,7 +131,7 @@ if (suggestion.isStarred()) { return SuggestionIcon.BOOKMARK; } else if (suggestion.getType() == OmniboxSuggestionType.HISTORY_URL) { - return mEnableSuggestionFavicons ? SuggestionIcon.GLOBE : SuggestionIcon.HISTORY; + return SuggestionIcon.HISTORY; } else { return SuggestionIcon.GLOBE; } @@ -142,8 +142,7 @@ case OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED: case OmniboxSuggestionType.SEARCH_HISTORY: - return mEnableSuggestionFavicons ? SuggestionIcon.MAGNIFIER - : SuggestionIcon.HISTORY; + return SuggestionIcon.HISTORY; default: return SuggestionIcon.MAGNIFIER;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java index 781fc41..b67de7cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java
@@ -602,6 +602,9 @@ private void confirmSettings() { RecordUserAction.record("Signin_Signin_ConfirmAdvancedSyncSettings"); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.SYNC_MANUAL_START_ANDROID)) { + ProfileSyncService.get().setFirstSetupComplete(); + } UnifiedConsentServiceBridge.recordSyncSetupDataTypesHistogram(); // Settings will be applied when mSyncSetupInProgressHandle is released in onDestroy. getActivity().finish();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncPreferenceUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncPreferenceUtils.java index 361d772..bc320d8e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncPreferenceUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncPreferenceUtils.java
@@ -11,6 +11,7 @@ import android.net.Uri; import android.provider.Browser; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceFragmentCompat; @@ -29,8 +30,6 @@ import org.chromium.components.sync.StopSource; import org.chromium.ui.UiUtils; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Helper methods for sync preferences. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java index 5e65be5a..b505c73 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragment.java
@@ -12,8 +12,10 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.sync.SyncAndServicesPreferences; +import org.chromium.chrome.browser.sync.ProfileSyncService; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -137,6 +139,9 @@ PreferencesLauncher.launchSettingsPage(getActivity(), SyncAndServicesPreferences.class, SyncAndServicesPreferences.createArguments(true)); + } else if (ChromeFeatureList.isEnabled( + ChromeFeatureList.SYNC_MANUAL_START_ANDROID)) { + ProfileSyncService.get().setFirstSetupComplete(); } recordSigninCompletedHistogramAccountInfo();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java index d14bb2f0..da6e38b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ProfileSyncService.java
@@ -12,6 +12,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.components.sync.ModelType; import org.chromium.components.sync.Passphrase; @@ -451,8 +452,10 @@ assert mSetupInProgressCounter > 0; if (--mSetupInProgressCounter == 0) { setSetupInProgress(false); - // The user has finished setting up sync at least once. - setFirstSetupComplete(); + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SYNC_MANUAL_START_ANDROID)) { + // The user has finished setting up sync at least once. + setFirstSetupComplete(); + } } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java index b714c536..6692173 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
@@ -13,6 +13,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.support.customtabs.CustomTabsIntent; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; @@ -42,8 +43,6 @@ import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier.SpanInfo; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Dialog to ask to user to enter their sync passphrase. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java index 2f26f0f..3f337695 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java
@@ -10,6 +10,7 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.support.customtabs.CustomTabsIntent; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; import android.text.SpannableString; @@ -38,8 +39,6 @@ import java.util.Date; import java.util.List; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Dialog to ask the user select what type of password to use for encryption. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index bee31fac..63a844a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -11,6 +11,7 @@ import android.net.Uri; import android.provider.Browser; import android.provider.ContactsContract; +import android.support.customtabs.CustomTabsIntent; import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordUserAction; @@ -36,8 +37,6 @@ import java.net.URI; import java.util.Locale; -import androidx.browser.customtabs.CustomTabsIntent; - /** * A default {@link ContextMenuItemDelegate} that supports the context menu functionality in Tab. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java index 400be28..98e684b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/usage_stats/UsageStatsService.java
@@ -68,12 +68,12 @@ mSuspensionTracker = new SuspensionTracker(mBridge, mNotificationSuspender); mTokenTracker = new TokenTracker(mBridge); mPageViewObservers = new ArrayList<>(); + mClient = AppHooks.get().createDigitalWellbeingClient(); mSuspensionTracker.getAllSuspendedWebsites().then( (suspendedSites) -> { notifyObserversOfSuspensions(suspendedSites, true); }); mOptInState = getOptInState(); - mClient = AppHooks.get().createDigitalWellbeingClient(); } /* package */ NotificationSuspender getNotificationSuspender() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java index d3fb555..13415c9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/SplashController.java
@@ -166,6 +166,11 @@ return mSplashView; } + @VisibleForTesting + public boolean wasSplashScreenHiddenForTests() { + return mSplashShownTimestamp > 0 && mSplashView == null; + } + @Override public void onPreInflationStartup() { mDidPreInflationStartup = true;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index c467487..fc79a59 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -814,8 +814,8 @@ } @VisibleForTesting - View getSplashScreenForTests() { - return mSplashController.getSplashScreenForTests(); + SplashController getSplashControllerForTests() { + return mSplashController; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java index d327fd70..49cda5b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappInfo.java
@@ -10,6 +10,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.Bitmap; import android.net.Uri; +import android.support.customtabs.CustomTabsSessionToken; import android.text.TextUtils; import org.chromium.base.ContextUtils; @@ -22,8 +23,6 @@ import org.chromium.content_public.common.ScreenOrientationValues; import org.chromium.webapk.lib.common.splash.SplashLayout; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Stores info about a web app. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappTabDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappTabDelegate.java index b1e0f83..be2e6e2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappTabDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappTabDelegate.java
@@ -9,6 +9,7 @@ import android.net.Uri; import android.os.StrictMode; import android.provider.Browser; +import android.support.customtabs.CustomTabsIntent; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -26,8 +27,6 @@ import java.net.URISyntaxException; import java.util.List; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Asynchronously creates Tabs for navigation originating from an installed PWA. *
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java index 02e5753e..310017d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/OriginVerifierTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.browserservices; import android.net.Uri; +import android.support.customtabs.CustomTabsService; import android.support.test.filters.SmallTest; import org.junit.Assert; @@ -36,8 +37,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import androidx.browser.customtabs.CustomTabsService; - /** Tests for OriginVerifier. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java index ccf87f7..00364e5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
@@ -13,6 +13,7 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.rule.ServiceTestRule; @@ -37,8 +38,6 @@ import java.util.concurrent.TimeoutException; -import androidx.browser.trusted.TrustedWebActivityServiceConnectionManager; - /** * Tests the TrustedWebActivityClient. *
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java index c719db2..3ee1926 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityTest.java
@@ -8,6 +8,9 @@ import static org.junit.Assert.assertTrue; import android.content.Intent; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.TrustedWebUtils; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; @@ -34,10 +37,6 @@ import java.util.concurrent.TimeoutException; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.TrustedWebUtils; - /** * Instrumentation tests for launching * {@link org.chromium.chrome.browser.customtabs.CustomTabActivity} in Trusted Web Activity Mode.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/ClientManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/ClientManagerTest.java index b9fc507..df2f619 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/ClientManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/ClientManagerTest.java
@@ -7,6 +7,9 @@ import android.content.Context; import android.net.Uri; import android.os.Process; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.PostMessageServiceConnection; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -29,10 +32,6 @@ import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.customtabs.PostMessageServiceConnection; - /** Tests for ClientManager. */ @RunWith(BaseJUnit4ClassRunner.class) public class ClientManagerTest { @@ -174,10 +173,7 @@ @SmallTest public void testPostMessageOriginVerification() { final ClientManager cm = mClientManager; - // TODO(peconn): Get rid of this anonymous class once PostMessageServiceConnection is made - // non-abstract. Same with the other occurrences below. - PostMessageServiceConnection serviceConnection = - new PostMessageServiceConnection(mSession) {}; + PostMessageServiceConnection serviceConnection = new PostMessageServiceConnection(mSession); Assert.assertTrue(cm.newSession(mSession, mUid, null, new PostMessageHandler(serviceConnection), serviceConnection)); // Should always start with no origin. @@ -220,8 +216,7 @@ @SmallTest public void testPostMessageOriginDifferentRelations() { final ClientManager cm = mClientManager; - PostMessageServiceConnection serviceConnection = - new PostMessageServiceConnection(mSession) {}; + PostMessageServiceConnection serviceConnection = new PostMessageServiceConnection(mSession); Assert.assertTrue(cm.newSession(mSession, mUid, null, new PostMessageHandler(serviceConnection), serviceConnection)); // Should always start with no origin. @@ -260,8 +255,7 @@ @SmallTest public void testPostMessageOriginHttpNotAllowed() { final ClientManager cm = mClientManager; - PostMessageServiceConnection serviceConnection = - new PostMessageServiceConnection(mSession) {}; + PostMessageServiceConnection serviceConnection = new PostMessageServiceConnection(mSession); Assert.assertTrue(cm.newSession(mSession, mUid, null, new PostMessageHandler(serviceConnection), serviceConnection)); // Should always start with no origin.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java index 5b5b132..cf1768ac 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityIncognitoTest.java
@@ -6,6 +6,7 @@ import android.content.Intent; import android.graphics.Color; +import android.support.customtabs.CustomTabsIntent; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.view.MenuItem; @@ -31,8 +32,6 @@ import java.util.concurrent.ExecutionException; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Instrumentation tests for {@link CustomTabActivity} launched in incognito mode. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 6761dd7..2dd5efa 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -34,6 +34,11 @@ import android.os.Bundle; import android.os.SystemClock; import android.support.annotation.DrawableRes; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSession; +import android.support.customtabs.CustomTabsSessionToken; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; @@ -138,12 +143,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSession; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Instrumentation tests for app menu, context menu, and toolbar of a {@link CustomTabActivity}. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java index ec03c34..e63f864 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsConnectionTest.java
@@ -13,6 +13,12 @@ import android.os.Build; import android.os.Bundle; import android.os.Process; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsClient; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsServiceConnection; +import android.support.customtabs.CustomTabsSession; +import android.support.customtabs.CustomTabsSessionToken; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -45,13 +51,6 @@ import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsClient; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsServiceConnection; -import androidx.browser.customtabs.CustomTabsSession; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** Tests for CustomTabsConnection. */ @RunWith(ChromeJUnit4ClassRunner.class) public class CustomTabsConnectionTest {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java index 86e2116e..2c9929c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java
@@ -10,6 +10,12 @@ import android.net.Uri; import android.os.Bundle; import android.os.Process; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsClient; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsServiceConnection; +import android.support.customtabs.CustomTabsSession; +import android.support.customtabs.CustomTabsSessionToken; import android.support.test.InstrumentationRegistry; import org.junit.Assert; @@ -25,13 +31,6 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsClient; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsServiceConnection; -import androidx.browser.customtabs.CustomTabsSession; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Utility class that contains convenience calls related with custom tabs testing. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java index 6734ed1..0945878 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
@@ -9,6 +9,11 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSession; +import android.support.customtabs.CustomTabsSessionToken; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -48,12 +53,6 @@ import java.util.List; import java.util.concurrent.TimeoutException; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.CustomTabsSession; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** Tests for detached resource requests. */ @RunWith(ChromeJUnit4ClassRunner.class) public class DetachedResourceRequestTest {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java index 47545e7c..a031eaa5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/TrustedCdnPublisherUrlTest.java
@@ -12,6 +12,8 @@ import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsSessionToken; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.util.Pair; @@ -67,9 +69,6 @@ import java.util.Locale; import java.util.concurrent.TimeoutException; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * Instrumentation tests for showing the publisher URL for a trusted CDN. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleNavigationTest.java index 12963bdf5..6fb583bb 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleNavigationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleNavigationTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.customtabs.dynamicmodule; import android.content.Intent; +import android.support.customtabs.CustomTabsCallback; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -47,8 +48,6 @@ import java.util.List; import java.util.concurrent.TimeoutException; -import androidx.browser.customtabs.CustomTabsCallback; - /** * Instrumentation tests for the CustomTabsDynamicModuleNavigationObserver. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModulePostMessageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModulePostMessageTest.java index d9443ba..f8e36c76 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModulePostMessageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModulePostMessageTest.java
@@ -12,6 +12,8 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.PostMessageBackend; import android.support.test.filters.SmallTest; import org.junit.After; @@ -39,9 +41,6 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.net.test.util.TestWebServer; -import androidx.browser.customtabs.CustomTabsService; -import androidx.browser.customtabs.PostMessageBackend; - /** * Instrumentation tests for the CCT Dynamic Module post message API. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java index f791d70..ff4bca4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java
@@ -20,6 +20,7 @@ import android.os.Bundle; import android.os.SystemClock; import android.support.annotation.Nullable; +import android.support.customtabs.CustomTabsCallback; import android.support.test.InstrumentationRegistry; import org.junit.Assert; @@ -35,8 +36,6 @@ import java.io.InputStream; import java.util.concurrent.TimeoutException; -import androidx.browser.customtabs.CustomTabsCallback; - /** * Utility class that contains fake CCT dynamic module classes and convenience calls * related with CCT dynamic module testing.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java index 1961cdd..ab7b3b01 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -16,6 +16,7 @@ import android.os.Bundle; import android.os.SystemClock; import android.provider.Browser; +import android.support.customtabs.CustomTabsIntent; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.test.mock.MockPackageManager; @@ -51,8 +52,6 @@ import java.util.List; import java.util.regex.Pattern; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Instrumentation tests for {@link ExternalNavigationHandler}. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java index 5c0bdfa9..b757859 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkIntegrationTest.java
@@ -42,7 +42,6 @@ import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.common.ContentSwitches; -import org.chromium.net.test.EmbeddedTestServerRule; import org.chromium.webapk.lib.client.WebApkValidator; import org.chromium.webapk.lib.common.WebApkConstants; @@ -55,8 +54,6 @@ public final NativeLibraryTestRule mNativeLibraryTestRule = new NativeLibraryTestRule(); - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - public MockCertVerifierRuleAndroid mCertVerifierRule = new MockCertVerifierRuleAndroid(mNativeLibraryTestRule, 0 /* net::OK */); @@ -64,8 +61,7 @@ public RuleChain mRuleChain = RuleChain.emptyRuleChain() .around(mActivityTestRule) .around(mNativeLibraryTestRule) - .around(mCertVerifierRule) - .around(mTestServerRule); + .around(mCertVerifierRule); private static final long STARTUP_TIMEOUT = ScalableTimeout.scaleTimeout(10000); @@ -100,7 +96,9 @@ CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - return mActivityTestRule.getActivity().getSplashScreenForTests() == null; + return mActivityTestRule.getActivity() + .getSplashControllerForTests() + .wasSplashScreenHiddenForTests(); } }); } @@ -121,8 +119,9 @@ @Before public void setUp() throws Exception { WebApkUpdateManager.setUpdatesEnabledForTesting(false); - mTestServerRule.setServerUsesHttps(true); - Uri mapToUri = Uri.parse(mTestServerRule.getServer().getURL("/")); + mActivityTestRule.getEmbeddedTestServerRule().setServerUsesHttps(true); + Uri mapToUri = + Uri.parse(mActivityTestRule.getEmbeddedTestServerRule().getServer().getURL("/")); CommandLine.getInstance().appendSwitchWithValue( ContentSwitches.HOST_RESOLVER_RULES, "MAP * " + mapToUri.getAuthority()); WebApkValidator.disableValidationForTesting();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java index 38d5d314..e589293 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestRule.java
@@ -8,6 +8,7 @@ import android.content.Intent; import android.net.Uri; +import android.support.customtabs.TrustedWebUtils; import android.support.test.InstrumentationRegistry; import android.view.View; import android.view.ViewGroup; @@ -28,8 +29,6 @@ import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; -import androidx.browser.customtabs.TrustedWebUtils; - /** * Custom {@link ChromeActivityTestRule} for tests using {@link WebappActivity}. */ @@ -225,7 +224,8 @@ // We also wait till the splash screen has finished initializing. if (getActivity().getActivityTab() == null) return false; - View splashScreen = getActivity().getSplashScreenForTests(); + View splashScreen = + getActivity().getSplashControllerForTests().getSplashScreenForTests(); if (splashScreen == null) return false; return (!(splashScreen instanceof ViewGroup) @@ -234,10 +234,9 @@ }, STARTUP_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - View splashScreen = getActivity().getSplashScreenForTests(); - if (splashScreen == null) { - Assert.fail("No splash screen available."); - } + View splashScreen = getActivity().getSplashControllerForTests().getSplashScreenForTests(); + Assert.assertNotNull("No splash screen available.", splashScreen); + // TODO(pkotwicz): Change return type in order to accommodate new-style WebAPKs. // (crbug.com/958288) return (splashScreen instanceof ViewGroup) ? (ViewGroup) splashScreen : null; @@ -256,6 +255,6 @@ } public boolean isSplashScreenVisible() { - return getActivity().getSplashScreenForTests() != null; + return getActivity().getSplashControllerForTests().getSplashScreenForTests() != null; } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/SessionDataHolderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/SessionDataHolderTest.java index 7d18a33..2297878 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/SessionDataHolderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/SessionDataHolderTest.java
@@ -12,6 +12,8 @@ import android.app.Activity; import android.app.PendingIntent; import android.content.Intent; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsSessionToken; import org.junit.Before; import org.junit.Test; @@ -29,9 +31,6 @@ import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.customtabs.TranslucentCustomTabActivity; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** Unit tests for {@link SessionDataHolder}. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java index dd1ee52..3176221 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/TrustedWebActivityClientTest.java
@@ -15,6 +15,9 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.RemoteException; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager; +import android.support.customtabs.trusted.TrustedWebActivityServiceConnectionManager.ExecutionCallback; +import android.support.customtabs.trusted.TrustedWebActivityServiceWrapper; import org.junit.Before; import org.junit.Test; @@ -29,10 +32,6 @@ import org.chromium.chrome.browser.notifications.NotificationBuilderBase; import org.chromium.chrome.browser.notifications.NotificationUmaTracker; -import androidx.browser.trusted.TrustedWebActivityServiceConnectionManager; -import androidx.browser.trusted.TrustedWebActivityServiceConnectionManager.ExecutionCallback; -import androidx.browser.trusted.TrustedWebActivityServiceWrapper; - /** * Unit tests for {@link TrustedWebActivityClient}. */
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java index 13e33886..836d35c 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
@@ -4,12 +4,14 @@ package org.chromium.chrome.browser.customtabs; +import static android.support.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK; +import static android.support.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT; + import static org.junit.Assert.assertEquals; -import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK; -import static androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT; - import android.content.Intent; +import android.support.customtabs.CustomTabColorSchemeParams; +import android.support.customtabs.CustomTabsIntent; import org.junit.Test; import org.junit.runner.RunWith; @@ -18,9 +20,6 @@ import org.chromium.base.test.BaseRobolectricTestRunner; -import androidx.browser.customtabs.CustomTabColorSchemeParams; -import androidx.browser.customtabs.CustomTabsIntent; - /** Tests for {@link CustomTabIntentDataProvider}. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE)
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java index 4b3f827..726128a8 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/content/CustomTabActivityContentTestEnvironment.java
@@ -13,6 +13,7 @@ import android.content.Intent; import android.os.Bundle; +import android.support.customtabs.CustomTabsSessionToken; import android.view.View; import org.junit.rules.TestWatcher; @@ -54,8 +55,6 @@ import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.WebContents; -import androidx.browser.customtabs.CustomTabsSessionToken; - /** * A TestRule that sets up the mocks and contains helper methods for JUnit/Robolectric tests scoped * to the content layer of Custom Tabs code.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/FutureTaskConsumerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FutureTaskConsumerTest.java new file mode 100644 index 0000000..0f575ae --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/FutureTaskConsumerTest.java
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.feed; + +import static org.junit.Assert.assertEquals; + +import android.support.test.filters.SmallTest; + +import com.google.android.libraries.feed.common.functional.Consumer; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.Callback; +import org.chromium.base.test.BaseRobolectricTestRunner; + +/** Unit tests for {@link FutureTaskConsumer}. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class FutureTaskConsumerTest { + @Test + @SmallTest + public void testConsume() { + Integer expected = 42; + Integer failure = -1; + + Callback<Consumer<Integer>> callback = new Callback<Consumer<Integer>>() { + @Override + public void onResult(Consumer<Integer> result) { + result.accept(expected); + } + }; + + Integer actual = FutureTaskConsumer.consume("", callback, failure); + + assertEquals(expected, actual); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java index d2806eb..e1317c0 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunIntegrationUnitTest.java
@@ -11,6 +11,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserManager; +import android.support.customtabs.CustomTabsIntent; import org.junit.Assert; import org.junit.Before; @@ -42,8 +43,6 @@ import org.chromium.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.webapk.test.WebApkTestHelper; -import androidx.browser.customtabs.CustomTabsIntent; - /** JUnit tests for first run triggering code. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE,
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorTest.java index 8c041a3..205da3b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/suggestions/basic/BasicSuggestionProcessorTest.java
@@ -11,20 +11,15 @@ import org.junit.Assert; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; -import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion; import org.chromium.chrome.browser.omnibox.suggestions.basic.SuggestionViewProperties.SuggestionIcon; -import org.chromium.chrome.test.util.browser.Features; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.testing.local.LocalRobolectricTestRunner; import org.chromium.ui.modelutil.PropertyModel; @@ -85,8 +80,6 @@ Resources mResources; @Mock SuggestionHost mSuggestionHost; - @Rule - public TestRule mFeatureProcessor = new Features.JUnitProcessor(); @Before public void setUp() { @@ -156,39 +149,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.OMNIBOX_SHOW_SUGGESTION_FAVICONS) - public void getSuggestionIconTypeForSearch_FavIcons() { - mProcessor.onNativeInitialized(); - int[][] testSuites = { - {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.HISTORY_URL, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.HISTORY_TITLE, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.HISTORY_BODY, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.HISTORY_KEYWORD, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.NAVSUGGEST, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_HISTORY, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_SUGGEST, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_SUGGEST_TAIL, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_SUGGEST_PROFILE, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.SEARCH_OTHER_ENGINE, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.NAVSUGGEST_PERSONALIZED, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.CLIPBOARD_URL, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.VOICE_SUGGEST, SuggestionIcon.VOICE}, - {OmniboxSuggestionType.DOCUMENT_SUGGESTION, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.PEDAL, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.CLIPBOARD_TEXT, SuggestionIcon.MAGNIFIER}, - {OmniboxSuggestionType.CLIPBOARD_IMAGE, SuggestionIcon.MAGNIFIER}, - }; - - for (int[] test : testSuites) { - assertSuggestionIconTypeIs(createSearchSuggestion(test[0]), test[1]); - } - } - - @Test public void getSuggestionIconTypeForUrl_Default() { int[][] testSuites = { {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.GLOBE}, @@ -220,39 +180,6 @@ } @Test - @EnableFeatures(ChromeFeatureList.OMNIBOX_SHOW_SUGGESTION_FAVICONS) - public void getSuggestionIconTypeForUrl_FavIcons() { - mProcessor.onNativeInitialized(); - int[][] testSuites = { - {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.HISTORY_URL, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.HISTORY_TITLE, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.HISTORY_BODY, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.HISTORY_KEYWORD, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.NAVSUGGEST, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_HISTORY, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_SUGGEST, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_SUGGEST_TAIL, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_SUGGEST_PROFILE, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.SEARCH_OTHER_ENGINE, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.NAVSUGGEST_PERSONALIZED, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.CLIPBOARD_URL, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.VOICE_SUGGEST, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.DOCUMENT_SUGGESTION, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.PEDAL, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.CLIPBOARD_TEXT, SuggestionIcon.GLOBE}, - {OmniboxSuggestionType.CLIPBOARD_IMAGE, SuggestionIcon.GLOBE}, - }; - - for (int[] test : testSuites) { - assertSuggestionIconTypeIs(createUrlSuggestion(test[0]), test[1]); - } - } - - @Test public void getSuggestionIconTypeForBookmarks_Default() { int[][] testSuites = { {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.BOOKMARK}, @@ -282,37 +209,4 @@ assertSuggestionIconTypeIs(createBookmarkSuggestion(test[0]), test[1]); } } - - @Test - @EnableFeatures(ChromeFeatureList.OMNIBOX_SHOW_SUGGESTION_FAVICONS) - public void getSuggestionIconTypeForBookmarks_FavIcons() { - mProcessor.onNativeInitialized(); - int[][] testSuites = { - {OmniboxSuggestionType.URL_WHAT_YOU_TYPED, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.HISTORY_URL, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.HISTORY_TITLE, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.HISTORY_BODY, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.HISTORY_KEYWORD, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.NAVSUGGEST, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_HISTORY, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_SUGGEST, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_SUGGEST_TAIL, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_SUGGEST_PERSONALIZED, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_SUGGEST_PROFILE, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.SEARCH_OTHER_ENGINE, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.NAVSUGGEST_PERSONALIZED, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.CLIPBOARD_URL, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.VOICE_SUGGEST, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.DOCUMENT_SUGGESTION, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.PEDAL, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.CLIPBOARD_TEXT, SuggestionIcon.BOOKMARK}, - {OmniboxSuggestionType.CLIPBOARD_IMAGE, SuggestionIcon.BOOKMARK}, - }; - - for (int[] test : testSuites) { - assertSuggestionIconTypeIs(createBookmarkSuggestion(test[0]), test[1]); - } - } }
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessTabDelegate.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessTabDelegate.java index 92a7084..b26af1a 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessTabDelegate.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessTabDelegate.java
@@ -6,6 +6,7 @@ import android.content.Intent; import android.net.Uri; import android.provider.Browser; +import android.support.customtabs.CustomTabsIntent; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.IntentHandler; @@ -19,8 +20,6 @@ import org.chromium.chrome.browser.tabmodel.document.TabDelegate; import org.chromium.chrome.browser.util.UrlUtilities; -import androidx.browser.customtabs.CustomTabsIntent; - /** * Asynchronously creates Tabs for navigation originating from {@link NoTouchActivity}. *
diff --git a/chrome/app/OWNERS b/chrome/app/OWNERS index 2b82288..423a023 100644 --- a/chrome/app/OWNERS +++ b/chrome/app/OWNERS
@@ -19,6 +19,8 @@ per-file app_management_strings.grdp=file://chrome/browser/ui/webui/app_management/OWNERS +per-file global_media_controls_strings.grdp=file://chrome/browser/ui/global_media_controls/OWNERS + per-file media_router_strings.grdp=file://chrome/browser/media/router/OWNERS per-file onboarding_welcome_strings.grdp=file://chrome/browser/ui/webui/welcome/OWNERS
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 03f3c74..f569e738 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -194,6 +194,9 @@ <!-- Media Router specific strings --> <part file="media_router_strings.grdp" /> + <!-- Global Media Controls specific strings --> + <part file="global_media_controls_strings.grdp" /> + <!-- Profiles specific strings --> <part file="profiles_strings.grdp" />
diff --git a/chrome/app/global_media_controls_strings.grdp b/chrome/app/global_media_controls_strings.grdp new file mode 100644 index 0000000..4ee94f6 --- /dev/null +++ b/chrome/app/global_media_controls_strings.grdp
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Global Media Controls-specific strings (included from generated_resources.grd). --> +<grit-part> + <message name="IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT" desc="Tooltip for the Global Media Controls icon, which appears in the toolbar. The tooltip appears on mouseover of the icon."> + Global Media Controls + </message> +</grit-part>
diff --git a/chrome/app/global_media_controls_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT.png.sha1 b/chrome/app/global_media_controls_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT.png.sha1 new file mode 100644 index 0000000..78b8e905 --- /dev/null +++ b/chrome/app/global_media_controls_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT.png.sha1
@@ -0,0 +1 @@ +6c90b12caf43ac61e604d1b867dfc10e0dbbb9b2 \ No newline at end of file
diff --git a/chrome/app/global_media_controls_strings_grdp/OWNERS b/chrome/app/global_media_controls_strings_grdp/OWNERS new file mode 100644 index 0000000..399a33f --- /dev/null +++ b/chrome/app/global_media_controls_strings_grdp/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/ui/global_media_controls/OWNERS
diff --git a/chrome/app/global_media_controls_strings_grdp/README.md b/chrome/app/global_media_controls_strings_grdp/README.md new file mode 100644 index 0000000..f013bb5 --- /dev/null +++ b/chrome/app/global_media_controls_strings_grdp/README.md
@@ -0,0 +1,5 @@ +This directory of image SHA-1 hashes is used to improve translations of UI +strings through context images for translators. + +See also: [Chrome Translation Screenshots - Instructions & FAQ +](https://docs.google.com/document/d/1nwYWDny20icMSpLUuV_LgrlbWKrYpbXOERUIZNH636o/edit#heading=h.2t7lc4cxo2au) \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 5793ae2..09dffde 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1067,10 +1067,6 @@ {"predictor", ui::input_prediction::kScrollPredictorNameLsq}}; const FeatureEntry::FeatureParam kResamplingInputEventsKalmanEnabled[] = { {"predictor", ui::input_prediction::kScrollPredictorNameKalman}}; -const FeatureEntry::FeatureParam - kResamplingInputEventsKalmanTimeFilteredEnabled[] = { - {"predictor", - ui::input_prediction::kScrollPredictorNameKalmanTimeFiltered}}; const FeatureEntry::FeatureParam kResamplingInputEventsLinearFirstEnabled[] = { {"predictor", ui::input_prediction::kScrollPredictorNameLinearFirst}}; const FeatureEntry::FeatureParam kResamplingInputEventsLinearSecondEnabled[] = { @@ -1083,9 +1079,6 @@ {ui::input_prediction::kScrollPredictorNameKalman, kResamplingInputEventsKalmanEnabled, base::size(kResamplingInputEventsKalmanEnabled), nullptr}, - {ui::input_prediction::kScrollPredictorNameKalmanTimeFiltered, - kResamplingInputEventsKalmanTimeFilteredEnabled, - base::size(kResamplingInputEventsKalmanTimeFilteredEnabled), nullptr}, {ui::input_prediction::kScrollPredictorNameLinearFirst, kResamplingInputEventsLinearFirstEnabled, base::size(kResamplingInputEventsLinearFirstEnabled), nullptr},
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 9bf0dad..5c315f9 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -848,25 +848,6 @@ return crash_handler->GetDeathSignalSocket(); } -#if defined(OS_CHROMEOS) - // Mash services are utility processes, but crashes are reported using the - // service name as the process type to make the crash console easier to read. - if (command_line.HasSwitch(switches::kMashServiceName)) { - static base::NoDestructor< - std::map<std::string, breakpad::CrashHandlerHostLinux*>> - crash_handlers; - std::string service_name = - command_line.GetSwitchValueASCII(switches::kMashServiceName); - auto it = crash_handlers->find(service_name); - if (it == crash_handlers->end()) { - auto insert_result = crash_handlers->insert( - std::make_pair(service_name, CreateCrashHandlerHost(service_name))); - it = insert_result.first; - } - return it->second->GetDeathSignalSocket(); - } -#endif // defined(OS_CHROMEOS) - std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType);
diff --git a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc index b1078c8..7a2eb4e8 100644 --- a/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc +++ b/chrome/browser/chromeos/arc/enterprise/cert_store/arc_cert_installer_utils_unittest.cc
@@ -150,6 +150,6 @@ ArcCertInstallerUtilsTest, testing::Values("", "name of the smart card", - std::string("A", 2048))); + std::string(2048, 'A'))); } // namespace arc
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.h b/chrome/browser/chromeos/login/lock/screen_locker.h index ca846c6..69587c9 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.h +++ b/chrome/browser/chromeos/login/lock/screen_locker.h
@@ -207,7 +207,7 @@ // lock request is failed. void OnStartLockCallback(bool locked); - // Callback to be invoked when the |cert_provider_based_auth_preparer_| + // Callback to be invoked when the |challenge_response_auth_keys_loader_| // completes building the currently available challenge-response keys. Used // only during the challenge-response unlock. void OnChallengeResponseKeysPrepared(
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc index 24c3788a..820763f2 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/authpolicy/authpolicy_helper.h" #include "chrome/browser/chromeos/lock_screen_apps/state_controller.h" +#include "chrome/browser/chromeos/login/challenge_response_auth_keys_loader.h" #include "chrome/browser/chromeos/login/lock_screen_utils.h" #include "chrome/browser/chromeos/login/mojo_system_info_dispatcher.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h" @@ -35,6 +36,7 @@ #include "chromeos/components/proximity_auth/screenlock_bridge.h" #include "chromeos/dbus/media_perception/media_perception.pb.h" #include "components/user_manager/known_user.h" +#include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "google_apis/gaia/gaia_auth_util.h" #include "ui/base/ime/chromeos/ime_keyboard.h" @@ -105,14 +107,6 @@ input_method::InputMethodManager::Get()->GetImeKeyboard()->SetCapsLockEnabled( false); - // Enable pin for any users who can use it. - if (user_manager::UserManager::IsInitialized()) { - for (user_manager::User* user : - user_manager::UserManager::Get()->GetLoggedInUsers()) { - UpdatePinKeyboardState(user->GetAccountId()); - } - } - system_info_updater_->StartRequest(); ash::LoginScreen::Get()->GetModel()->SetUserList( @@ -120,15 +114,12 @@ ash::LoginScreen::Get()->SetAllowLoginAsGuest(false /*show_guest*/); if (user_manager::UserManager::IsInitialized()) { + // Enable pin and challenge-response authentication for any users who can + // use them. for (user_manager::User* user : user_manager::UserManager::Get()->GetLoggedInUsers()) { - const bool enable_challenge_response = - ChallengeResponseAuthKeysLoader::CanAuthenticateUser( - user->GetAccountId()); - ash::LoginScreen::Get() - ->GetModel() - ->SetChallengeResponseAuthEnabledForUser(user->GetAccountId(), - enable_challenge_response); + UpdatePinKeyboardState(user->GetAccountId()); + UpdateChallengeResponseAuthAvailability(user->GetAccountId()); } } @@ -335,6 +326,14 @@ weak_factory_.GetWeakPtr(), account_id)); } +void ViewsScreenLocker::UpdateChallengeResponseAuthAvailability( + const AccountId& account_id) { + const bool enable_challenge_response = + ChallengeResponseAuthKeysLoader::CanAuthenticateUser(account_id); + ash::LoginScreen::Get()->GetModel()->SetChallengeResponseAuthEnabledForUser( + account_id, enable_challenge_response); +} + void ViewsScreenLocker::OnAllowedInputMethodsChanged() { if (focused_pod_account_id_) { std::string user_input_method = lock_screen_utils::GetUserLastInputMethod(
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.h b/chrome/browser/chromeos/login/lock/views_screen_locker.h index fa6e528c..e5e015e 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.h +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.h
@@ -83,6 +83,7 @@ private: void UpdatePinKeyboardState(const AccountId& account_id); + void UpdateChallengeResponseAuthAvailability(const AccountId& account_id); void OnAllowedInputMethodsChanged(); void OnPinCanAuthenticate(const AccountId& account_id, bool can_authenticate); void OnExternalBinaryAuthTimeout();
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc index 96dc935..5de9007 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc +++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.cc
@@ -4,11 +4,11 @@ #include "chrome/browser/chromeos/login/ui/login_display_host_mojo.h" -#include <string> #include <utility> #include "ash/public/cpp/login_screen.h" #include "base/bind.h" +#include "base/callback.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/mojo_system_info_dispatcher.h" @@ -22,6 +22,8 @@ #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h" #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" #include "chromeos/login/auth/user_context.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" #include "components/user_manager/user_names.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -352,8 +354,18 @@ void LoginDisplayHostMojo::HandleAuthenticateUserWithChallengeResponse( const AccountId& account_id, base::OnceCallback<void(bool)> callback) { - // TODO(crbug.com/826417): Implement the challenge-response system for login. - std::move(callback).Run(false); + if (!ChallengeResponseAuthKeysLoader::CanAuthenticateUser(account_id)) { + LOG(ERROR) + << "Challenge-response authentication isn't supported for the user"; + std::move(callback).Run(false); + return; + } + + challenge_response_auth_keys_loader_.LoadAvailableKeys( + account_id, + base::BindOnce(&LoginDisplayHostMojo::OnChallengeResponseKeysPrepared, + weak_factory_.GetWeakPtr(), account_id, + std::move(callback))); } void LoginDisplayHostMojo::HandleHardlockPod(const AccountId& account_id) { @@ -428,4 +440,28 @@ login_display_.get()); } +void LoginDisplayHostMojo::OnChallengeResponseKeysPrepared( + const AccountId& account_id, + base::OnceCallback<void(bool)> on_auth_complete_callback, + std::vector<ChallengeResponseKey> challenge_response_keys) { + if (challenge_response_keys.empty()) { + // TODO(crbug.com/826417): Indicate the error in the UI. + std::move(on_auth_complete_callback).Run(false); + return; + } + + CHECK(!pending_auth_state_); + pending_auth_state_ = std::make_unique<AuthState>( + account_id, std::move(on_auth_complete_callback)); + + const user_manager::User* const user = + user_manager::UserManager::Get()->FindUser(account_id); + DCHECK(user); + UserContext user_context(*user); + *user_context.GetMutableChallengeResponseKeys() = + std::move(challenge_response_keys); + + existing_user_controller_->Login(user_context, chromeos::SigninSpecifics()); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h index 3ec24b3..946912d0 100644 --- a/chrome/browser/chromeos/login/ui/login_display_host_mojo.h +++ b/chrome/browser/chromeos/login/ui/login_display_host_mojo.h
@@ -9,13 +9,16 @@ #include <string> #include <vector> +#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "chrome/browser/chromeos/login/challenge_response_auth_keys_loader.h" #include "chrome/browser/chromeos/login/ui/login_display_host_common.h" #include "chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h" #include "chrome/browser/ui/ash/login_screen_client.h" #include "chromeos/login/auth/auth_status_consumer.h" +#include "chromeos/login/auth/challenge_response_key.h" namespace chromeos { @@ -125,6 +128,14 @@ private: void LoadOobeDialog(); + // Callback to be invoked when the |challenge_response_auth_keys_loader_| + // completes building the currently available challenge-response keys. Used + // only during the challenge-response authentication. + void OnChallengeResponseKeysPrepared( + const AccountId& account_id, + base::OnceCallback<void(bool)> on_auth_complete_callback, + std::vector<ChallengeResponseKey> challenge_response_keys); + // State associated with a pending authentication attempt. struct AuthState { AuthState(AccountId account_id, base::OnceCallback<void(bool)> callback); @@ -165,6 +176,8 @@ // first OnStartSigninScreen and remains true afterward. bool signin_screen_started_ = false; + ChallengeResponseAuthKeysLoader challenge_response_auth_keys_loader_; + base::WeakPtrFactory<LoginDisplayHostMojo> weak_factory_; DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostMojo);
diff --git a/chrome/browser/chromeos/login/ui/login_display_mojo.cc b/chrome/browser/chromeos/login/ui/login_display_mojo.cc index ec94c87..ccd6e6d 100644 --- a/chrome/browser/chromeos/login/ui/login_display_mojo.cc +++ b/chrome/browser/chromeos/login/ui/login_display_mojo.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" +#include "chrome/browser/chromeos/login/challenge_response_auth_keys_loader.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h" #include "chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h" @@ -49,6 +50,14 @@ weak_factory_.GetWeakPtr(), account_id)); } +void LoginDisplayMojo::UpdateChallengeResponseAuthAvailability( + const AccountId& account_id) { + const bool enable_challenge_response = + ChallengeResponseAuthKeysLoader::CanAuthenticateUser(account_id); + ash::LoginScreen::Get()->GetModel()->SetChallengeResponseAuthEnabledForUser( + account_id, enable_challenge_response); +} + void LoginDisplayMojo::ClearAndEnablePassword() {} void LoginDisplayMojo::Init(const user_manager::UserList& filtered_users, @@ -72,10 +81,12 @@ ash::LoginScreen::Get()->SetAllowLoginAsGuest(show_guest); user_selection_screen->SetUsersLoaded(true /*loaded*/); - // Enable pin for any users who can use it. if (user_manager::UserManager::IsInitialized()) { + // Enable pin and challenge-response authentication for any users who can + // use them. for (const user_manager::User* user : filtered_users) { UpdatePinKeyboardState(user->GetAccountId()); + UpdateChallengeResponseAuthAvailability(user->GetAccountId()); } }
diff --git a/chrome/browser/chromeos/login/ui/login_display_mojo.h b/chrome/browser/chromeos/login/ui/login_display_mojo.h index 6ba39f3..3588f11 100644 --- a/chrome/browser/chromeos/login/ui/login_display_mojo.h +++ b/chrome/browser/chromeos/login/ui/login_display_mojo.h
@@ -27,8 +27,9 @@ explicit LoginDisplayMojo(LoginDisplayHostMojo* host); ~LoginDisplayMojo() override; - // Updates the state of the PIN keyboard. + // Updates the state of the authentication methods supported for the user. void UpdatePinKeyboardState(const AccountId& account_id); + void UpdateChallengeResponseAuthAvailability(const AccountId& account_id); // LoginDisplay: void ClearAndEnablePassword() override;
diff --git a/chrome/browser/chromeos/printing/cups_print_job_manager.h b/chrome/browser/chromeos/printing/cups_print_job_manager.h index 701ab90..2a0af18b 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_manager.h +++ b/chrome/browser/chromeos/printing/cups_print_job_manager.h
@@ -23,7 +23,7 @@ class CupsPrintJobManager : public KeyedService { public: - class Observer { + class Observer : public base::CheckedObserver { public: virtual void OnPrintJobCreated(base::WeakPtr<CupsPrintJob> job) {} virtual void OnPrintJobStarted(base::WeakPtr<CupsPrintJob> job) {} @@ -44,7 +44,7 @@ virtual void OnPrintJobCancelled(base::WeakPtr<CupsPrintJob> job) {} protected: - virtual ~Observer() {} + ~Observer() override {} }; static CupsPrintJobManager* CreateInstance(Profile* profile); @@ -80,7 +80,7 @@ void RecordJobDuration(base::WeakPtr<CupsPrintJob> job); std::unique_ptr<CupsPrintJobNotificationManager> notification_manager_; - base::ObserverList<Observer>::Unchecked observers_; + base::ObserverList<Observer> observers_; // Keyed by CupsPrintJob's unique ID std::map<std::string, base::TimeTicks> print_job_start_times_;
diff --git a/chrome/browser/chromeos/printing/cups_print_job_notification.cc b/chrome/browser/chromeos/printing/cups_print_job_notification.cc index 57aa8a3..d7b213c6 100644 --- a/chrome/browser/chromeos/printing/cups_print_job_notification.cc +++ b/chrome/browser/chromeos/printing/cups_print_job_notification.cc
@@ -97,6 +97,7 @@ switch (button_commands_[*button_index]) { case ButtonCommand::CANCEL_PRINTING: DCHECK(print_job_); + cancelled_by_user_ = true; print_job_manager->CancelPrintJob(print_job_.get()); // print_job_ was deleted in CancelPrintJob. Forget the pointer. @@ -105,7 +106,6 @@ // Clean up the notification. NotificationDisplayService::GetForProfile(profile_)->Close( NotificationHandler::Type::TRANSIENT, notification_id_); - cancelled_by_user_ = true; notification_manager_->OnPrintJobNotificationRemoved(this); break; case ButtonCommand::PAUSE_PRINTING:
diff --git a/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc b/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc index 58d7dd95..6b04785 100644 --- a/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc +++ b/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.cc
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/shared_memory.h" #include "base/memory/weak_ptr.h" +#include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/threading/thread_task_runner_handle.h" #include "base/unguessable_token.h" @@ -36,6 +37,18 @@ namespace chromeos { +// List of extension URLs that will communicate with wilco_dtc +// through the extensions native messaging system. +// +// Note: the list size must be kept in sync with +// |kWilcoDtcSupportdHostOriginsSize|. +const char* const kWilcoDtcSupportdHostOrigins[] = { + "chrome-extension://echlnkcmdobkdgcjgjbiceoceeoenjkj/"}; + +// Size of |kWilcoDtcSupportdHostOrigins| array. +const size_t kWilcoDtcSupportdHostOriginsSize = + base::size(kWilcoDtcSupportdHostOrigins); + // Native application name that is used for passing UI messages between the // wilco_dtc daemon and extensions. const char kWilcoDtcSupportdUiMessageHost[] = "com.google.wilco_dtc"; @@ -52,16 +65,6 @@ namespace { -// List of extension IDs that will receive UI messages from the wilco_dtc -// through the extensions native messaging system. -// -// Note: the list must be kept in sync with the allowed origins list in -// src/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc. -// -// TODO(crbug.com/907932,b/123926112): Populate the list once extension IDs are -// determined. -const char* const kAllowedExtensionIds[] = {}; - // Extensions native message host implementation that is used when an // extension requests a message channel to the wilco_dtc daemon. // @@ -372,10 +375,12 @@ std::vector<std::pair<Profile*, std::string>> recipient_extensions; for (auto* profile : g_browser_process->profile_manager()->GetLoadedProfiles()) { - for (const auto* extension_id : kAllowedExtensionIds) { + for (const auto* extension_url : kWilcoDtcSupportdHostOrigins) { + GURL url = GURL(extension_url); if (extensions::ExtensionRegistry::Get(profile) ->enabled_extensions() - .GetByID(extension_id)) { + .GetExtensionOrAppByURL(url)) { + std::string extension_id = url.host(); recipient_extensions.emplace_back(profile, extension_id); } }
diff --git a/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.h b/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.h index f3fcc2a..d3e3dbeb 100644 --- a/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.h +++ b/chrome/browser/chromeos/wilco_dtc_supportd/wilco_dtc_supportd_messaging.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_CHROMEOS_WILCO_DTC_SUPPORTD_WILCO_DTC_SUPPORTD_MESSAGING_H_ #define CHROME_BROWSER_CHROMEOS_WILCO_DTC_SUPPORTD_WILCO_DTC_SUPPORTD_MESSAGING_H_ +#include <stddef.h> #include <memory> #include <string> @@ -16,6 +17,10 @@ namespace chromeos { +extern const char* const kWilcoDtcSupportdHostOrigins[]; + +extern const size_t kWilcoDtcSupportdHostOriginsSize; + extern const char kWilcoDtcSupportdUiMessageHost[]; extern const char kWilcoDtcSupportdUiMessageTooBigExtensionsError[];
diff --git a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc index 1ba3053c..078befe 100644 --- a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc +++ b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
@@ -127,7 +127,9 @@ {arc::ArcSupportMessageHost::kHostName, arc::ArcSupportMessageHost::kHostOrigin, 1, &arc::ArcSupportMessageHost::Create}, - {chromeos::kWilcoDtcSupportdUiMessageHost, nullptr, 0, + {chromeos::kWilcoDtcSupportdUiMessageHost, + chromeos::kWilcoDtcSupportdHostOrigins, + chromeos::kWilcoDtcSupportdHostOriginsSize, &chromeos::CreateExtensionOwnedWilcoDtcSupportdMessageHost}, };
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc index 5516d337..8882b4eb0 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -8,13 +8,18 @@ #include "base/strings/stringprintf.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/policy/browser_dm_token_storage.h" #include "chrome/browser/policy/chrome_browser_policy_connector.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/common/extensions/api/safe_browsing_private.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" #include "components/policy/core/common/cloud/device_management_service.h" +#include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "content/public/browser/browser_context.h" #include "extensions/browser/event_router.h" @@ -58,6 +63,30 @@ InitRealtimeReportingClient(); } +// TODO(rogerta): once new event types are implemented, will likely want to +// move this to a more common place. +base::Value BuildRealtimeReport(Profile* profile, base::Value event) { + base::Value context(base::Value::Type::DICTIONARY); + + ProfileAttributesStorage& storage = + g_browser_process->profile_manager()->GetProfileAttributesStorage(); + ProfileAttributesEntry* entry = nullptr; + if (storage.GetProfileAttributesWithPath(profile->GetPath(), &entry)) { + context.SetStringPath("profile.profileName", entry->GetName()); + context.SetStringPath("profile.gaiaEmail", entry->GetUserName()); + } + + context.SetStringPath("profile.profilePath", profile->GetPath().value()); + context.SetStringPath("browser.userAgent", GetUserAgent()); + + base::Value report(base::Value::Type::DICTIONARY); + report.SetKey(policy::RealtimeReportingJobConfiguration::kContextKey, + std::move(context)); + report.SetKey(policy::RealtimeReportingJobConfiguration::kEventKey, + std::move(event)); + return report; +} + SafeBrowsingPrivateEventRouter::~SafeBrowsingPrivateEventRouter() {} void SafeBrowsingPrivateEventRouter::OnPolicySpecifiedPasswordReuseDetected( @@ -242,7 +271,7 @@ if (!identity_manager_) return; - // |device_management_service| may be null in tests. If there is no device + // |device_management_service| may be null in tests. If there is no device // management service don't enable the real-time reporting API since the // router won't be able to create the reporting server client below. policy::DeviceManagementService* device_management_service = @@ -300,7 +329,10 @@ wrapper.SetStringKey("time", now_str); wrapper.SetKey(name, std::move(event)); - client_->UploadRealtimeReport(std::move(wrapper), base::DoNothing()); + client_->UploadRealtimeReport( + BuildRealtimeReport(Profile::FromBrowserContext(context_), + std::move(wrapper)), + base::DoNothing()); } std::string SafeBrowsingPrivateEventRouter::GetProfileUserName() {
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc index bf670267..f0a9a724 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc
@@ -10,8 +10,11 @@ #include "base/values.h" #include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h" #include "chrome/common/extensions/api/safe_browsing_private.h" +#include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" +#include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h" #include "content/public/test/test_browser_thread_bundle.h" #include "extensions/browser/test_event_router.h" #include "testing/gmock/include/gmock/gmock.h" @@ -67,44 +70,49 @@ class SafeBrowsingPrivateEventRouterTest : public testing::Test { public: - SafeBrowsingPrivateEventRouterTest() = default; + SafeBrowsingPrivateEventRouterTest() + : profile_manager_(TestingBrowserProcess::GetGlobal()) { + EXPECT_TRUE(profile_manager_.SetUp()); + profile_ = profile_manager_.CreateTestingProfile("test-user"); + } + ~SafeBrowsingPrivateEventRouterTest() override = default; void TriggerOnPolicySpecifiedPasswordReuseDetectedEvent() { - SafeBrowsingPrivateEventRouterFactory::GetForProfile(&profile_) + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->OnPolicySpecifiedPasswordReuseDetected(GURL("https://phishing.com/"), "user_name_1", /*is_phishing_url*/ true); } void TriggerOnPolicySpecifiedPasswordChangedEvent() { - SafeBrowsingPrivateEventRouterFactory::GetForProfile(&profile_) + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->OnPolicySpecifiedPasswordChanged("user_name_2"); } void TriggerOnDangerousDownloadOpenedEvent() { - SafeBrowsingPrivateEventRouterFactory::GetForProfile(&profile_) + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->OnDangerousDownloadOpened(GURL("https://evil.com/malware.exe"), "/path/to/malware.exe", "sha256_or_malware_exe"); } void TriggerOnSecurityInterstitialShownEvent() { - SafeBrowsingPrivateEventRouterFactory::GetForProfile(&profile_) + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->OnSecurityInterstitialShown(GURL("https://phishing.com/"), "PHISHING", 0); } void TriggerOnSecurityInterstitialProceededEvent() { - SafeBrowsingPrivateEventRouterFactory::GetForProfile(&profile_) + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->OnSecurityInterstitialProceeded(GURL("https://phishing.com/"), "PHISHING", -201); } void SetUpRouters() { - event_router_ = extensions::CreateAndUseTestEventRouter(&profile_); + event_router_ = extensions::CreateAndUseTestEventRouter(profile_); SafeBrowsingPrivateEventRouterFactory::GetInstance()->SetTestingFactory( - &profile_, base::BindRepeating(&BuildSafeBrowsingPrivateEventRouter)); + profile_, base::BindRepeating(&BuildSafeBrowsingPrivateEventRouter)); // Make sure real-time feature is eanbled so that the tests will run. scoped_feature_list_.InitAndEnableFeature( @@ -115,14 +123,15 @@ // manage expectations. client_ = new policy::MockCloudPolicyClient(); std::unique_ptr<policy::CloudPolicyClient> client(client_); - SafeBrowsingPrivateEventRouterFactory::GetForProfile(&profile_) + SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_) ->SetCloudPolicyClientForTesting(std::move(client)); } protected: content::TestBrowserThreadBundle thread_bundle_; base::test::ScopedFeatureList scoped_feature_list_; - TestingProfile profile_; + TestingProfileManager profile_manager_; + TestingProfile* profile_; extensions::TestEventRouter* event_router_ = nullptr; policy::MockCloudPolicyClient* client_; @@ -137,9 +146,9 @@ kEventName); event_router_->AddEventObserver(&event_observer); - base::Value wrapper; + base::Value report; EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) - .WillOnce(CaptureArg(&wrapper)); + .WillOnce(CaptureArg(&report)); TriggerOnPolicySpecifiedPasswordReuseDetectedEvent(); base::RunLoop().RunUntilIdle(); @@ -149,9 +158,13 @@ EXPECT_EQ("user_name_1", captured_args.FindKey("userName")->GetString()); Mock::VerifyAndClearExpectations(client_); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* wrapper = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); + ASSERT_NE(nullptr, wrapper); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); base::Value* event = - wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent); + wrapper->FindKey(SafeBrowsingPrivateEventRouter::kKeyPasswordReuseEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("https://phishing.com/", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyUrl)); @@ -165,9 +178,9 @@ api::safe_browsing_private::OnPolicySpecifiedPasswordChanged::kEventName); event_router_->AddEventObserver(&event_observer); - base::Value wrapper; + base::Value report; EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) - .WillOnce(CaptureArg(&wrapper)); + .WillOnce(CaptureArg(&report)); TriggerOnPolicySpecifiedPasswordChangedEvent(); base::RunLoop().RunUntilIdle(); @@ -176,9 +189,13 @@ EXPECT_EQ("user_name_2", captured_args.GetString()); Mock::VerifyAndClearExpectations(client_); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); - base::Value* event = - wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent); + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* wrapper = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); + ASSERT_NE(nullptr, wrapper); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); + base::Value* event = wrapper->FindKey( + SafeBrowsingPrivateEventRouter::kKeyPasswordChangedEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("user_name_2", *event->FindStringKey( SafeBrowsingPrivateEventRouter::kKeyUserName)); @@ -190,9 +207,9 @@ api::safe_browsing_private::OnDangerousDownloadOpened::kEventName); event_router_->AddEventObserver(&event_observer); - base::Value wrapper; + base::Value report; EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) - .WillOnce(CaptureArg(&wrapper)); + .WillOnce(CaptureArg(&report)); TriggerOnDangerousDownloadOpenedEvent(); base::RunLoop().RunUntilIdle(); @@ -207,8 +224,12 @@ captured_args.FindKey("downloadDigestSha256")->GetString()); Mock::VerifyAndClearExpectations(client_); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); - base::Value* event = wrapper.FindKey( + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* wrapper = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); + ASSERT_NE(nullptr, wrapper); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); + base::Value* event = wrapper->FindKey( SafeBrowsingPrivateEventRouter::kKeyDangerousDownloadEvent); EXPECT_NE(nullptr, event); EXPECT_EQ( @@ -223,9 +244,9 @@ api::safe_browsing_private::OnSecurityInterstitialProceeded::kEventName); event_router_->AddEventObserver(&event_observer); - base::Value wrapper; + base::Value report; EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) - .WillOnce(CaptureArg(&wrapper)); + .WillOnce(CaptureArg(&report)); TriggerOnSecurityInterstitialProceededEvent(); base::RunLoop().RunUntilIdle(); @@ -237,9 +258,13 @@ EXPECT_EQ("", captured_args.FindKey("userName")->GetString()); Mock::VerifyAndClearExpectations(client_); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* wrapper = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); + ASSERT_NE(nullptr, wrapper); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); base::Value* event = - wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); + wrapper->FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("PHISHING", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyReason)); @@ -255,9 +280,9 @@ api::safe_browsing_private::OnSecurityInterstitialShown::kEventName); event_router_->AddEventObserver(&event_observer); - base::Value wrapper; + base::Value report; EXPECT_CALL(*client_, UploadRealtimeReport(_, _)) - .WillOnce(CaptureArg(&wrapper)); + .WillOnce(CaptureArg(&report)); TriggerOnSecurityInterstitialShownEvent(); base::RunLoop().RunUntilIdle(); @@ -269,9 +294,13 @@ EXPECT_EQ("", captured_args.FindKey("userName")->GetString()); Mock::VerifyAndClearExpectations(client_); - EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper.type()); + EXPECT_EQ(base::Value::Type::DICTIONARY, report.type()); + base::Value* wrapper = + report.FindKey(policy::RealtimeReportingJobConfiguration::kEventKey); + ASSERT_NE(nullptr, wrapper); + EXPECT_EQ(base::Value::Type::DICTIONARY, wrapper->type()); base::Value* event = - wrapper.FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); + wrapper->FindKey(SafeBrowsingPrivateEventRouter::kKeyInterstitialEvent); EXPECT_NE(nullptr, event); EXPECT_EQ("PHISHING", *event->FindStringKey(SafeBrowsingPrivateEventRouter::kKeyReason));
diff --git a/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.cc b/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.cc index 511f922..d916775 100644 --- a/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.cc +++ b/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.cc
@@ -12,6 +12,15 @@ ReputationWebContentsObserver::~ReputationWebContentsObserver() {} +void ReputationWebContentsObserver::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + if (!navigation_handle->IsInMainFrame() || + navigation_handle->IsSameDocument()) { + return; + } + last_shown_safety_tip_type_ = SafetyTipType::kNone; +} + void ReputationWebContentsObserver::DidFinishNavigation( content::NavigationHandle* navigation_handle) { if (!navigation_handle->IsInMainFrame()) { @@ -52,6 +61,7 @@ return; } + last_shown_safety_tip_type_ = type; ShowSafetyTipDialog(web_contents(), type, url); #endif // !defined(OS_ANDROID) }
diff --git a/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.h b/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.h index 2c33457..c9309f18 100644 --- a/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.h +++ b/chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.h
@@ -29,9 +29,15 @@ ~ReputationWebContentsObserver() override; // content::WebContentsObserver: + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; + SafetyTipType last_shown_safety_tip_type() const { + return last_shown_safety_tip_type_; + } + private: friend class content::WebContentsUserData<ReputationWebContentsObserver>; @@ -44,6 +50,10 @@ const GURL& url); Profile* profile_; + // Used to cache the last shown safety tip type so that Page Info can fetch + // this information without performing a reputation check. Resets to kNone on + // new top frame navigations. + safety_tips::SafetyTipType last_shown_safety_tip_type_ = SafetyTipType::kNone; base::WeakPtrFactory<ReputationWebContentsObserver> weak_factory_; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc index 49c3dd3..9f250a5 100644 --- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc +++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.cc
@@ -32,8 +32,9 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) #include "chrome/browser/extensions/extension_service.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" -#include "extensions/browser/info_map.h" +#include "extensions/browser/extension_util.h" #include "extensions/browser/process_manager.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -165,29 +166,33 @@ // This function is security sensitive. Be sure to check with a security // person before you modify it. -bool NaClBrowserDelegateImpl::MapUrlToLocalFilePath( - const GURL& file_url, - bool use_blocking_api, - const base::FilePath& profile_directory, - base::FilePath* file_path) { +NaClBrowserDelegate::MapUrlToLocalFilePathCallback +NaClBrowserDelegateImpl::GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_EXTENSIONS) - scoped_refptr<extensions::InfoMap> extension_info_map = - GetExtensionInfoMap(profile_directory); - return extension_info_map->MapUrlToLocalFilePath( - file_url, use_blocking_api, file_path); + auto extensions = std::make_unique<extensions::ExtensionSet>(); + extensions->InsertAll( + extensions::ExtensionRegistry::Get( + profile_manager_->GetProfileByPath(profile_directory)) + ->enabled_extensions()); + return base::BindRepeating(&extensions::util::MapUrlToLocalFilePath, + base::Owned(std::move(extensions))); #else - return false; + return base::BindRepeating([](const GURL& url, bool use_blocking_api, + base::FilePath* file_path) { return false; }); #endif } bool NaClBrowserDelegateImpl::IsNonSfiModeAllowed( const base::FilePath& profile_directory, const GURL& manifest_url) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); #if BUILDFLAG(ENABLE_EXTENSIONS) - const extensions::ExtensionSet* extension_set = - &GetExtensionInfoMap(profile_directory)->extensions(); - return IsExtensionOrSharedModuleWhitelisted(manifest_url, extension_set, - allowed_nonsfi_origins_); + auto* registry = extensions::ExtensionRegistry::Get( + profile_manager_->GetProfileByPath(profile_directory)); + return IsExtensionOrSharedModuleWhitelisted( + manifest_url, ®istry->enabled_extensions(), allowed_nonsfi_origins_); #else return false; #endif @@ -209,16 +214,3 @@ if (infobar_service) NaClInfoBarDelegate::Create(infobar_service); } - -#if BUILDFLAG(ENABLE_EXTENSIONS) -scoped_refptr<extensions::InfoMap> NaClBrowserDelegateImpl::GetExtensionInfoMap( - const base::FilePath& profile_directory) { - // Get the profile associated with the renderer. - Profile* profile = profile_manager_->GetProfileByPath(profile_directory); - DCHECK(profile); - scoped_refptr<extensions::InfoMap> extension_info_map = - extensions::ExtensionSystem::Get(profile)->info_map(); - DCHECK(extension_info_map.get()); - return extension_info_map; -} -#endif
diff --git a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h index fdcc379..f7b02e6 100644 --- a/chrome/browser/nacl_host/nacl_browser_delegate_impl.h +++ b/chrome/browser/nacl_host/nacl_browser_delegate_impl.h
@@ -16,10 +16,6 @@ #if BUILDFLAG(ENABLE_EXTENSIONS) #include "base/memory/ref_counted.h" #include "extensions/common/url_pattern.h" - -namespace extensions { -class InfoMap; -} #endif class ProfileManager; @@ -39,10 +35,8 @@ std::string GetVersionString() const override; ppapi::host::HostFactory* CreatePpapiHostFactory( content::BrowserPpapiHost* ppapi_host) override; - bool MapUrlToLocalFilePath(const GURL& url, - bool is_blocking, - const base::FilePath& profile_directory, - base::FilePath* file_path) override; + MapUrlToLocalFilePathCallback GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) override; void SetDebugPatterns(const std::string& debug_patterns) override; bool URLMatchesDebugPatterns(const GURL& manifest_url) override; bool IsNonSfiModeAllowed(const base::FilePath& profile_directory, @@ -55,8 +49,6 @@ int render_view_id); #if BUILDFLAG(ENABLE_EXTENSIONS) - scoped_refptr<extensions::InfoMap> GetExtensionInfoMap( - const base::FilePath& profile_directory); std::vector<URLPattern> debug_patterns_; #endif
diff --git a/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc b/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc index 48e685c3..0816e28 100644 --- a/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc +++ b/chrome/browser/native_file_system/chrome_native_file_system_permission_context.cc
@@ -333,11 +333,10 @@ base::BindOnce(&WritePermissionGrantImpl::OnPermissionRequestComplete, this, std::move(callback))); - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&ShowWritePermissionPromptOnUIThread, process_id, frame_id, - origin_, path(), is_directory_, - std::move(result_callback))); + base::PostTask(FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&ShowWritePermissionPromptOnUIThread, + process_id, frame_id, origin_, path(), + is_directory_, std::move(result_callback))); } bool ChromeNativeFileSystemPermissionContext::WritePermissionGrantImpl:: @@ -492,7 +491,7 @@ int frame_id, base::OnceCallback<void(PermissionStatus)> callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( &ShowDirectoryAccessConfirmationPromptOnUIThread, process_id, @@ -526,7 +525,8 @@ // file selection is only supported if all files are in the same // directory. base::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, + FROM_HERE, + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce(&ShouldBlockAccessToPath, paths[0]), base::BindOnce(&ChromeNativeFileSystemPermissionContext:: DidConfirmSensitiveDirectoryAccess, @@ -688,7 +688,7 @@ auto result_callback = BindResultCallbackToCurrentSequence(std::move(callback)); - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce(&ShowNativeFileSystemRestrictedDirectoryDialogOnUIThread, process_id, frame_id, origin, paths[0],
diff --git a/chrome/browser/native_file_system/native_file_system_permission_request_manager.cc b/chrome/browser/native_file_system/native_file_system_permission_request_manager.cc index 21feff4..7cfbc3f 100644 --- a/chrome/browser/native_file_system/native_file_system_permission_request_manager.cc +++ b/chrome/browser/native_file_system/native_file_system_permission_request_manager.cc
@@ -74,7 +74,7 @@ if (!CanShowRequest()) return; - base::PostTaskWithTraits( + base::PostTask( FROM_HERE, {content::BrowserThread::UI}, base::BindOnce( &NativeFileSystemPermissionRequestManager::DequeueAndShowRequest,
diff --git a/chrome/browser/notifications/scheduler/internal/scheduler_utils_unittest.cc b/chrome/browser/notifications/scheduler/internal/scheduler_utils_unittest.cc index c476d787..ede5fe4 100644 --- a/chrome/browser/notifications/scheduler/internal/scheduler_utils_unittest.cc +++ b/chrome/browser/notifications/scheduler/internal/scheduler_utils_unittest.cc
@@ -25,7 +25,7 @@ void SetUp() override { config_.initial_daily_shown_per_type = 100; } - void InitFakeDay() { + void InitFakeClock() { clock_.SetNow(kFakeNow); ToLocalHour(0, clock_.Now(), 0, &beginning_of_today_); } @@ -87,7 +87,7 @@ TEST_F(SchedulerUtilsTest, NotificationsShownToday) { // Create fake client. auto new_client = CreateNewClientState(SchedulerClientType::kTest1, config()); - InitFakeDay(); + InitFakeClock(); base::Time now = clock()->Now(); // Test case 1: int count = NotificationsShownToday(new_client.get(), clock()); @@ -123,5 +123,6 @@ count = NotificationsShownToday(new_client.get(), clock()); EXPECT_EQ(count, 2); } + } // namespace } // namespace notifications
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index f0859b30..4a4720d 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -949,7 +949,7 @@ static const char kExpectedPDFAXTreePattern[] = "embeddedObject\n" - " group\n" + " document\n" " region 'Page 1'\n" " paragraph\n" " staticText '1 First Section'\n" @@ -2385,7 +2385,11 @@ AddPropertyFilter(property_filters, "value='*'"); // The value attribute on the document object contains the URL of the // current page which will not be the same every time the test is run. + // The PDF plugin uses the 'chrome-extension' protocol, so block that as + // well. AddPropertyFilter(property_filters, "value='http*'", PropertyFilter::DENY); + AddPropertyFilter(property_filters, "value='chrome-extension*'", + PropertyFilter::DENY); // Object attributes.value AddPropertyFilter(property_filters, "layout-guess:*", PropertyFilter::ALLOW); @@ -2395,6 +2399,7 @@ AddPropertyFilter(property_filters, "check*"); AddPropertyFilter(property_filters, "horizontal"); AddPropertyFilter(property_filters, "multiselectable"); + AddPropertyFilter(property_filters, "isPageBreakingObject*"); // Deny most empty values AddPropertyFilter(property_filters, "*=''", PropertyFilter::DENY); @@ -2435,3 +2440,7 @@ ParagraphsAndHeadingUntagged) { RunPDFTest(FILE_PATH_LITERAL("paragraphs-and-heading-untagged.pdf")); } + +IN_PROC_BROWSER_TEST_P(PDFExtensionAccessibilityTreeDumpTest, MultiPage) { + RunPDFTest(FILE_PATH_LITERAL("multi-page.pdf")); +}
diff --git a/chrome/browser/performance_manager/persistence/site_data/non_recording_site_data_cache_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/non_recording_site_data_cache_unittest.cc index bc694a3..d191d304 100644 --- a/chrome/browser/performance_manager/persistence/site_data/non_recording_site_data_cache_unittest.cc +++ b/chrome/browser/performance_manager/persistence/site_data/non_recording_site_data_cache_unittest.cc
@@ -23,11 +23,10 @@ NonRecordingSiteDataCacheTest() : use_in_memory_db_for_testing_( LevelDBSiteDataStore::UseInMemoryDBForTesting()), - factory_(SiteDataCacheFactory::CreateForTesting( - test_browser_thread_bundle_.GetMainThreadTaskRunner())), + factory_(std::make_unique<SiteDataCacheFactory>()), off_the_record_profile_(parent_profile_.GetOffTheRecordProfile()) {} - ~NonRecordingSiteDataCacheTest() override { factory_.reset(); } + ~NonRecordingSiteDataCacheTest() override = default; void SetUp() override { recording_data_cache_ = base::WrapUnique(new SiteDataCacheImpl( @@ -56,7 +55,7 @@ std::unique_ptr<base::AutoReset<bool>> use_in_memory_db_for_testing_; // The data cache factory that will be used by the caches tested here. - std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> factory_; + std::unique_ptr<SiteDataCacheFactory> factory_; // The on the record profile. TestingProfile parent_profile_;
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade.cc index 271b02d9..fc16b0731 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "chrome/browser/performance_manager/performance_manager.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl.h" #include "chrome/browser/profiles/incognito_helpers.h" @@ -16,6 +17,8 @@ namespace performance_manager { +class GraphImpl; + SiteDataCacheFacade::SiteDataCacheFacade( content::BrowserContext* browser_context) : browser_context_(browser_context) { @@ -45,10 +48,11 @@ void SiteDataCacheFacade::WaitUntilCacheInitializedForTesting() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); base::RunLoop run_loop; - SiteDataCacheFactory::GetInstance()->task_runner_for_testing()->PostTask( - FROM_HERE, base::Bind( + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, base::BindOnce( [](base::OnceClosure quit_closure, - const std::string browser_context_id) { + const std::string& browser_context_id, + GraphImpl* graph_unused) { auto* cache = SiteDataCacheFactory::GetInstance() ->GetDataCacheForBrowserContext( browser_context_id);
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_unittest.cc index c7b0717..6f153d6 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_unittest.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade_unittest.cc
@@ -5,25 +5,34 @@ #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_facade.h" #include "base/auto_reset.h" +#include "base/callback.h" #include "base/run_loop.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" +#include "chrome/browser/performance_manager/performance_manager.h" #include "chrome/browser/performance_manager/persistence/site_data/leveldb_site_data_store.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h" +#include "chrome/browser/performance_manager/persistence/site_data/unittest_utils.h" #include "chrome/test/base/testing_profile.h" -#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" namespace performance_manager { -TEST(SiteDataCacheFacadeTest, IsDataCacheRecordingForTesting) { - content::TestBrowserThreadBundle test_browser_thread_bundle; - std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> factory( - SiteDataCacheFactory::CreateForTesting(base::CreateSequencedTaskRunner({ - base::ThreadPool(), - }))); +using SiteDataCacheFacadeTest = testing::TestWithPerformanceManager; + +TEST_F(SiteDataCacheFacadeTest, IsDataCacheRecordingForTesting) { + // Create the SiteDataCacheFactory instance and pass it to the PM sequence for + // ownership. + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, + base::BindOnce( + [](std::unique_ptr<SiteDataCacheFactory> site_data_cache_factory, + performance_manager::GraphImpl* graph) { + graph->PassToGraph(std::move(site_data_cache_factory)); + }, + std::make_unique<SiteDataCacheFactory>())); TestingProfile profile; // Uses an in-memory database. @@ -34,24 +43,30 @@ SiteDataCacheFacade data_cache_facade(&profile); data_cache_facade.WaitUntilCacheInitializedForTesting(); - base::RunLoop run_loop; - data_cache_facade.IsDataCacheRecordingForTesting( - base::BindLambdaForTesting([&](bool is_recording) { - cache_is_recording = is_recording; - run_loop.QuitClosure().Run(); - })); - run_loop.Run(); + { + base::RunLoop run_loop; + auto quit_closure = run_loop.QuitClosure(); + data_cache_facade.IsDataCacheRecordingForTesting( + base::BindLambdaForTesting([&](bool is_recording) { + cache_is_recording = is_recording; + std::move(quit_closure).Run(); + })); + run_loop.Run(); + } EXPECT_TRUE(cache_is_recording); - base::RunLoop run_loop2; SiteDataCacheFacade off_record_data_cache_facade( profile.GetOffTheRecordProfile()); - off_record_data_cache_facade.IsDataCacheRecordingForTesting( - base::BindLambdaForTesting([&](bool is_recording) { - cache_is_recording = is_recording; - run_loop2.QuitClosure().Run(); - })); - run_loop2.Run(); + { + base::RunLoop run_loop; + auto quit_closure = run_loop.QuitClosure(); + off_record_data_cache_facade.IsDataCacheRecordingForTesting( + base::BindLambdaForTesting([&](bool is_recording) { + cache_is_recording = is_recording; + quit_closure.Run(); + })); + run_loop.Run(); + } EXPECT_FALSE(cache_is_recording); }
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc index bfc355fb..4d69bf2 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "base/bind.h" #include "base/sequenced_task_runner.h" #include "base/stl_util.h" #include "base/task_runner_util.h" @@ -26,10 +27,10 @@ return g_instance; } -SiteDataCacheFactory::SiteDataCacheFactory( - const scoped_refptr<base::SequencedTaskRunner> task_runner) - : task_runner_(task_runner) { +SiteDataCacheFactory::SiteDataCacheFactory() { DETACH_FROM_SEQUENCE(sequence_checker_); + DCHECK_EQ(nullptr, g_instance); + g_instance = this; } SiteDataCacheFactory::~SiteDataCacheFactory() { @@ -39,33 +40,6 @@ } // static -std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> -SiteDataCacheFactory::Create() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK_EQ(nullptr, g_instance); - // TODO(sebmarchand): Make this GraphOwned! - auto task_runner = PerformanceManager::GetInstance()->task_runner(); - std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> instance( - new SiteDataCacheFactory(task_runner), - base::OnTaskRunnerDeleter(task_runner)); - - g_instance = instance.get(); - return instance; -} - -// static -std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> -SiteDataCacheFactory::CreateForTesting( - const scoped_refptr<base::SequencedTaskRunner> task_runner) { - DCHECK_EQ(nullptr, g_instance); - std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> instance( - new SiteDataCacheFactory(task_runner), - base::OnTaskRunnerDeleter(task_runner)); - g_instance = instance.get(); - return instance; -} - -// static void SiteDataCacheFactory::OnBrowserContextCreatedOnUIThread( SiteDataCacheFactory* factory, content::BrowserContext* browser_context, @@ -81,9 +55,16 @@ DCHECK(browser_context->IsOffTheRecord()); parent_context_id = parent_context->UniqueId(); } - factory->task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&SiteDataCacheFactory::OnBrowserContextCreated, + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, base::BindOnce( + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + const base::FilePath& context_path, + base::Optional<std::string> parent_context_id, + GraphImpl* graph_unused) { + factory->OnBrowserContextCreated( + browser_context_id, context_path, parent_context_id); + }, base::Unretained(factory), browser_context->UniqueId(), browser_context->GetPath(), parent_context_id)); } @@ -94,11 +75,13 @@ content::BrowserContext* browser_context) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(factory); - // See OnBrowserContextCreatedOnUIThread for why it's safe to use a raw - // pointer in BindOnce. - factory->task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&SiteDataCacheFactory::OnBrowserContextDestroyed, + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, base::BindOnce( + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + performance_manager::GraphImpl* graph_unused) { + factory->OnBrowserContextDestroyed(browser_context_id); + }, base::Unretained(factory), browser_context->UniqueId())); } @@ -138,17 +121,17 @@ const std::string& browser_context_id, base::OnceCallback<void(bool)> cb) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - PostTaskAndReplyWithResult( - task_runner_.get(), FROM_HERE, + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, base::BindOnce( - [](SiteDataCacheFactory* tracker, - const std::string& browser_context_id) { - auto it = tracker->data_cache_map_.find(browser_context_id); - CHECK(it != tracker->data_cache_map_.end()); - return it->second->IsRecordingForTesting(); + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + base::OnceCallback<void(bool)> cb, GraphImpl* graph_unused) { + auto it = factory->data_cache_map_.find(browser_context_id); + CHECK(it != factory->data_cache_map_.end()); + std::move(cb).Run(it->second->IsRecordingForTesting()); }, - this, browser_context_id), - std::move(cb)); + this, browser_context_id, std::move(cb))); } void SiteDataCacheFactory::OnBrowserContextCreated(
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h index fb6657ce..efca2d03 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory.h
@@ -17,6 +17,7 @@ #include "base/sequence_checker.h" #include "base/sequenced_task_runner.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_cache.h" +#include "chrome/browser/performance_manager/public/graph/graph.h" #include "content/public/browser/browser_context.h" namespace content { @@ -30,9 +31,13 @@ // This class is responsible for tracking the SiteDataCache instances associated // with each browser context. It is meant to be used as a bridge between the // browser contexts living on the UI thread and the PerformanceManager sequence. -class SiteDataCacheFactory { +// +// This can be created on any sequence but it then should be passed to the +// graph and used on the PerformanceManager sequence. +class SiteDataCacheFactory : public GraphOwnedDefaultImpl { public: - ~SiteDataCacheFactory(); + SiteDataCacheFactory(); + ~SiteDataCacheFactory() override; // Retrieves the currently registered instance. // The caller needs to ensure that the lifetime of the registered instance @@ -40,21 +45,6 @@ // This function can be called from any sequence with those caveats. static SiteDataCacheFactory* GetInstance(); - // Creates, initializes and registers an instance. The created instance will - // use the task runner from PerformanceManager for all its operations and thus - // should be created after the PerformanceManager global instance. - // The instance will be deleted on the instance's task runner. - // - // This function should only be called from the UI thread. - static std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> - Create(); - - // Create an instance that will live and be destroyed on |task_runner|. - // - // This function should only be called from the UI thread. - static std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> - CreateForTesting(const scoped_refptr<base::SequencedTaskRunner> task_runner); - // Functions that should be called when a new browser context is created or // destroyed. They should be called from the UI thread, a task will then be // posted to the task_runner owned by |factory| to create the data store @@ -104,14 +94,7 @@ void IsDataCacheRecordingForTesting(const std::string& browser_context_id, base::OnceCallback<void(bool)> cb); - const scoped_refptr<base::SequencedTaskRunner> task_runner_for_testing() { - return task_runner_; - } - private: - explicit SiteDataCacheFactory( - const scoped_refptr<base::SequencedTaskRunner> task_runner); - // Implementation of the corresponding *OnUIThread public static functions // that runs on this object's task runner. void OnBrowserContextCreated(const std::string& browser_context_id, @@ -119,10 +102,6 @@ base::Optional<std::string> parent_context_id); void OnBrowserContextDestroyed(const std::string& browser_context_id); - // The task runner on which this object lives, this is expected to be the - // performance task runner in practice. - const scoped_refptr<base::SequencedTaskRunner> task_runner_; - // A map that associates a BrowserContext's ID with a SiteDataCache. This // object owns the caches. base::flat_map<std::string, std::unique_ptr<SiteDataCache>> data_cache_map_;
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc index 62f1191..1a5b2ba 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_factory_unittest.cc
@@ -10,75 +10,73 @@ #include "base/sequenced_task_runner.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" +#include "chrome/browser/performance_manager/persistence/site_data/unittest_utils.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { -class SiteDataCacheFactoryTest : public ::testing::Test { - protected: - SiteDataCacheFactoryTest() - : task_runner_(base::CreateSequencedTaskRunner({ - base::ThreadPool(), - })), - factory_(SiteDataCacheFactory::CreateForTesting(task_runner_)) {} - - ~SiteDataCacheFactoryTest() override { - factory_.reset(); - test_browser_thread_bundle_.RunUntilIdle(); - } - - void SetUp() override { - EXPECT_EQ(SiteDataCacheFactory::GetInstance(), factory_.get()); - } - - content::TestBrowserThreadBundle test_browser_thread_bundle_; - const scoped_refptr<base::SequencedTaskRunner> task_runner_; - std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> factory_; - TestingProfile profile_; - - DISALLOW_COPY_AND_ASSIGN(SiteDataCacheFactoryTest); -}; +using SiteDataCacheFactoryTest = testing::TestWithPerformanceManager; TEST_F(SiteDataCacheFactoryTest, EndToEnd) { - SiteDataCacheFactory::OnBrowserContextCreatedOnUIThread(factory_.get(), - &profile_, nullptr); - - base::RunLoop run_loop; - task_runner_->PostTask( + std::unique_ptr<SiteDataCacheFactory> factory = + std::make_unique<SiteDataCacheFactory>(); + SiteDataCacheFactory* factory_raw = factory.get(); + PerformanceManager::GetInstance()->CallOnGraph( FROM_HERE, base::BindOnce( - [](SiteDataCacheFactory* factory, - const std::string& browser_context_id, - base::OnceClosure quit_closure) { - DCHECK_NE(nullptr, factory->GetDataCacheForBrowserContext( - browser_context_id)); - DCHECK_NE(nullptr, factory->GetInspectorForBrowserContext( - browser_context_id)); - std::move(quit_closure).Run(); + [](std::unique_ptr<SiteDataCacheFactory> site_data_cache_factory, + performance_manager::GraphImpl* graph) { + graph->PassToGraph(std::move(site_data_cache_factory)); }, - factory_.get(), profile_.UniqueId(), run_loop.QuitClosure())); - run_loop.Run(); + std::move(factory))); - SiteDataCacheFactory::OnBrowserContextDestroyedOnUIThread(factory_.get(), - &profile_); + TestingProfile profile; + SiteDataCacheFactory::OnBrowserContextCreatedOnUIThread(factory_raw, &profile, + nullptr); - base::RunLoop run_loop2; - task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - [](SiteDataCacheFactory* factory, - const std::string& browser_context_id, - base::OnceClosure quit_closure) { - DCHECK_EQ(nullptr, factory->GetDataCacheForBrowserContext( - browser_context_id)); - DCHECK_EQ(nullptr, factory->GetInspectorForBrowserContext( - browser_context_id)); - std::move(quit_closure).Run(); - }, - factory_.get(), profile_.UniqueId(), run_loop.QuitClosure())); - test_browser_thread_bundle_.RunUntilIdle(); + { + base::RunLoop run_loop; + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, + base::BindOnce( + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + base::OnceClosure quit_closure, + performance_manager::GraphImpl* graph_unused) { + DCHECK_NE(nullptr, factory->GetDataCacheForBrowserContext( + browser_context_id)); + DCHECK_NE(nullptr, factory->GetInspectorForBrowserContext( + browser_context_id)); + std::move(quit_closure).Run(); + }, + base::Unretained(factory_raw), profile.UniqueId(), + run_loop.QuitClosure())); + run_loop.Run(); + } + + SiteDataCacheFactory::OnBrowserContextDestroyedOnUIThread(factory_raw, + &profile); + { + base::RunLoop run_loop; + PerformanceManager::GetInstance()->CallOnGraph( + FROM_HERE, + base::BindOnce( + [](SiteDataCacheFactory* factory, + const std::string& browser_context_id, + base::OnceClosure quit_closure, + performance_manager::GraphImpl* graph_unused) { + DCHECK_EQ(nullptr, factory->GetDataCacheForBrowserContext( + browser_context_id)); + DCHECK_EQ(nullptr, factory->GetInspectorForBrowserContext( + browser_context_id)); + std::move(quit_closure).Run(); + }, + base::Unretained(factory_raw), profile.UniqueId(), + run_loop.QuitClosure())); + run_loop.Run(); + } } } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc index c8536adc..7f92043 100644 --- a/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc +++ b/chrome/browser/performance_manager/persistence/site_data/site_data_cache_impl_unittest.cc
@@ -47,8 +47,7 @@ class SiteDataCacheImplTest : public ::testing::Test { protected: SiteDataCacheImplTest() - : data_cache_factory_(SiteDataCacheFactory::CreateForTesting( - test_browser_thread_bundle_.GetMainThreadTaskRunner())) { + : data_cache_factory_(std::make_unique<SiteDataCacheFactory>()) { PerformanceManagerClock::SetClockForTesting(&test_clock_); data_cache_ = std::make_unique<SiteDataCacheImpl>(profile_.UniqueId(), profile_.GetPath()); @@ -128,8 +127,7 @@ // Owned by |data_cache_|. ::testing::StrictMock<MockSiteCache>* mock_db_ = nullptr; - std::unique_ptr<SiteDataCacheFactory, base::OnTaskRunnerDeleter> - data_cache_factory_; + std::unique_ptr<SiteDataCacheFactory> data_cache_factory_; std::unique_ptr<SiteDataCacheImpl> data_cache_; std::unique_ptr<SiteDataReader> reader_;
diff --git a/chrome/browser/performance_manager/persistence/site_data/unittest_utils.cc b/chrome/browser/performance_manager/persistence/site_data/unittest_utils.cc index d39094f6..b69f31b9 100644 --- a/chrome/browser/performance_manager/persistence/site_data/unittest_utils.cc +++ b/chrome/browser/performance_manager/persistence/site_data/unittest_utils.cc
@@ -42,5 +42,24 @@ std::move(callback).Run(); } +TestWithPerformanceManager::TestWithPerformanceManager() = default; + +TestWithPerformanceManager::~TestWithPerformanceManager() = default; + +void TestWithPerformanceManager::SetUp() { + EXPECT_EQ(nullptr, PerformanceManager::GetInstance()); + performance_manager_ = PerformanceManager::Create(); + // Make sure creation registers the created instance. + EXPECT_EQ(performance_manager_.get(), PerformanceManager::GetInstance()); +} + +void TestWithPerformanceManager::TearDown() { + PerformanceManager::Destroy(std::move(performance_manager_)); + // Make sure destruction unregisters the instance. + EXPECT_EQ(nullptr, PerformanceManager::GetInstance()); + + test_browser_thread_bundle_.RunUntilIdle(); +} + } // namespace testing } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/persistence/site_data/unittest_utils.h b/chrome/browser/performance_manager/persistence/site_data/unittest_utils.h index 12a20dc..218f4a6b 100644 --- a/chrome/browser/performance_manager/persistence/site_data/unittest_utils.h +++ b/chrome/browser/performance_manager/persistence/site_data/unittest_utils.h
@@ -9,9 +9,12 @@ #include <vector> #include "base/macros.h" +#include "chrome/browser/performance_manager/performance_manager.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_impl.h" #include "chrome/browser/performance_manager/persistence/site_data/site_data_store.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { namespace testing { @@ -50,6 +53,21 @@ DISALLOW_COPY_AND_ASSIGN(NoopSiteDataStore); }; +class TestWithPerformanceManager : public ::testing::Test { + public: + TestWithPerformanceManager(); + ~TestWithPerformanceManager() override; + + void SetUp() override; + void TearDown() override; + + private: + std::unique_ptr<PerformanceManager> performance_manager_; + content::TestBrowserThreadBundle test_browser_thread_bundle_; + + DISALLOW_COPY_AND_ASSIGN(TestWithPerformanceManager); +}; + } // namespace testing } // namespace performance_manager
diff --git a/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js b/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js index 3dfc945..577c945 100644 --- a/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js +++ b/chrome/browser/resources/chromeos/set_time_dialog/set_time_dialog.js
@@ -267,11 +267,15 @@ applyTime_: function() { const now = this.getInputTime_(); - // Add timezone offset to get real time. - const timezoneDelta = getTimezoneDelta( - /** @type {string} */ (loadTimeData.getValue('currentTimezoneId')), - this.selectedTimezone_); - now.setMilliseconds(now.getMilliseconds() + timezoneDelta); + if (this.isTimezoneVisible_) { + // Add timezone offset to get real time. This is only necessary when the + // timezone was updated, which is only possible when the dropdown is + // visible. + const timezoneDelta = getTimezoneDelta( + /** @type {string} */ (loadTimeData.getValue('currentTimezoneId')), + this.selectedTimezone_); + now.setMilliseconds(now.getMilliseconds() + timezoneDelta); + } const seconds = Math.floor(now / 1000); this.browserProxy_.setTimeInSeconds(seconds);
diff --git a/chrome/browser/resources/chromeos/switch_access/menu_manager.js b/chrome/browser/resources/chromeos/switch_access/menu_manager.js index b480f97..1334a22 100644 --- a/chrome/browser/resources/chromeos/switch_access/menu_manager.js +++ b/chrome/browser/resources/chromeos/switch_access/menu_manager.js
@@ -45,6 +45,12 @@ /** * The node that the menu has been opened for. + * @private {chrome.automation.AutomationNode} + */ + this.menuOriginNode_; + + /** + * The node that the menu has been opened for. * @private {!chrome.automation.AutomationNode} */ this.menuOriginNode_ = desktop; @@ -56,6 +62,12 @@ this.inMenu_ = false; /** + * Keeps track of when there's a selection in the current node. + * @private {boolean} + */ + this.selectionExists_ = false; + + /** * Keeps track of when the clipboard is empty. * @private {boolean} */ @@ -111,6 +123,9 @@ chrome.accessibilityPrivate.setSwitchAccessMenuState( true, navNode.location, actions.length); this.menuOriginNode_ = navNode; + this.menuOriginNode_.addEventListener( + chrome.automation.EventType.TEXT_SELECTION_CHANGED, + this.onSelectionChanged_.bind(this), false /** Don't use capture. */); } else { console.log('Unable to show Switch Access menu.'); } @@ -161,6 +176,7 @@ } if (actionNode) { + this.menuOriginNode_ = navNode; this.node_ = actionNode; this.updateFocusRing_(); } @@ -175,8 +191,11 @@ if (this.node_) this.node_ = null; + this.menuOriginNode_.removeEventListener( + chrome.automation.EventType.TEXT_SELECTION_CHANGED, + this.onSelectionChanged_.bind(this), false /** Don't use capture. */); chrome.accessibilityPrivate.setSwitchAccessMenuState( - false, SAConstants.EMPTY_LOCATION, 0); + false /** Hide the menu. */, SAConstants.EMPTY_LOCATION, 0); } /** @@ -301,7 +320,9 @@ */ updateClipboardHasData() { this.clipboardHasData_ = true; - this.reloadMenu_(this.menuOriginNode_); + if (this.menuOriginNode_) { + this.reloadMenu_(this.menuOriginNode_); + } } /** @@ -313,6 +334,39 @@ } /** + * Returns if there is a selection in the current node. + * @private + * @returns {boolean} whether or not there's a selection + */ + nodeHasSelection_() { + let previousSelectionState = this.selectionExists_; + if (this.menuOriginNode_) { + if (this.menuOriginNode_.textSelStart !== + this.menuOriginNode_.textSelEnd) { + return true; + } else { + return false; + } + } + return false; + } + + /** + * Check to see if there is a change in the selection in the current node and + * reload the menu if so. + * @private + */ + onSelectionChanged_() { + let newSelectionState = this.nodeHasSelection_(); + if (this.selectionExists_ != newSelectionState) { + this.selectionExists_ = newSelectionState; + if (this.menuOriginNode_) { + this.reloadMenu_(this.menuOriginNode_); + } + } + } + + /** * Determines which menu actions are relevant, given the current node. If * there are no node-specific actions, return |null|, to indicate that we * should select the current node automatically. @@ -362,8 +416,10 @@ if (this.navigationManager_.selectionStarted()) { actions.push(SAConstants.MenuAction.SELECT_END); } - actions.push(SAConstants.MenuAction.CUT); - actions.push(SAConstants.MenuAction.COPY); + if (this.selectionExists_) { + actions.push(SAConstants.MenuAction.CUT); + actions.push(SAConstants.MenuAction.COPY); + } if (this.clipboardHasData_) { actions.push(SAConstants.MenuAction.PASTE); } @@ -470,7 +526,8 @@ break; case SAConstants.MenuAction.SELECT_START: this.navigationManager_.saveSelectStart(); - this.reloadMenu_(this.navigationManager_.currentNode()); + if (this.menuOriginNode_) + this.reloadMenu_(this.menuOriginNode_); exitAfterAction = false; break; case SAConstants.MenuAction.SELECT_END:
diff --git a/chrome/browser/resources/local_ntp/customize.css b/chrome/browser/resources/local_ntp/customize.css index 51efc24f2..7e0e808d 100644 --- a/chrome/browser/resources/local_ntp/customize.css +++ b/chrome/browser/resources/local_ntp/customize.css
@@ -296,6 +296,13 @@ z-index: 10000; } +/* Prevent footer from overlapping with header at small window heights. */ +@media only screen and (max-height: 116px) { + #bg-sel-menu { + max-height: 116px; + } +} + @media (prefers-color-scheme: dark) { #bg-sel-menu { background-color: rgb(var(--dark-mode-dialog-rgb));
diff --git a/chrome/browser/resources/safety_tips/PRESUBMIT.py b/chrome/browser/resources/safety_tips/PRESUBMIT.py new file mode 100644 index 0000000..766fec6 --- /dev/null +++ b/chrome/browser/resources/safety_tips/PRESUBMIT.py
@@ -0,0 +1,50 @@ +# Copyright 2019 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. + +"""Presubmit checks for Safety Tips proto for the component updater. +""" + +"""Returns true if any line in changed_contents contains the string |s|. +|changed_contents| is a tuple containing (line number, line text) pairs. +""" +def ContainsLine(changed_contents, s): + for _, line in changed_contents: + if line.strip().startswith(s): + return True + return False + +def CheckVersionUpdatedInProto(input_api, output_api): + def IsSafetyTipProto(x): + return (input_api.os_path.basename(x.LocalPath()) == + 'safety_tips.asciipb') + + safety_tips_proto = input_api.AffectedFiles(file_filter=IsSafetyTipProto) + if not safety_tips_proto: + return [] + + contents = safety_tips_proto[0].ChangedContents() + # Must not have any changes containing flagged_page: + if ContainsLine(contents, 'flagged_page:'): + return [output_api.PresubmitError( + 'Do not check in the full safety_tips.asciipb proto. ' + 'Only increment |version_id|.')] + + # It's enticing to do something fancy like checking whether the ID was in fact + # incremented or whether this is a whitespace-only or comment-only change. + # However, currently deleted lines don't show up in ChangedContents() and + # attempting to parse the asciipb file any more than we are doing above is + # likely not worth the trouble. + # + # At worst, the submitter can skip the presubmit check on upload if it isn't + # correct. + if not ContainsLine(contents, 'version_id:'): + return [output_api.PresubmitError( + 'Increment |version_id| in safety_tips.asciipb if you are ' + 'updating the file types proto.')] + + return [] + + +def CheckChangeOnUpload(input_api, output_api): + return CheckVersionUpdatedInProto(input_api, output_api)
diff --git a/chrome/browser/resources/safety_tips/README.md b/chrome/browser/resources/safety_tips/README.md new file mode 100644 index 0000000..7fc21e08 --- /dev/null +++ b/chrome/browser/resources/safety_tips/README.md
@@ -0,0 +1,29 @@ +### Update Instructions for Safety Tips Component + +Safety Tips component pushes binary protos to clients via Chrome's component +updater. The proto files are stored in a Google Cloud Storage bucket +(`gs://chrome-components-safety-tips`) under versioned directories +(e.g. `gs://chrome-components-safety-tips/5/all` for version `5`, `all` for all +platforms). + +Follow these instructions to write binary protos under versioned directories: + + 1. Overwrite `safety_tips.asciipb` with the data. Don't forget to increment + `version_id`. + 2. Build the binary proto: `ninja -C out/Release`. This will write the binary +proto at `out/Release/gen/chrome/browser/resources/safety_tips/safety_tips.pb`. + 3. Push the binary proto to cloud storage: + `chrome/browser/resources/safety_tips/push_proto.py -d out/Release` + 4. Revert `safety_tips.asciipb`, update `version_id` only for future reference + and check it in. + 5. In a day or two, navigate to chrome://components on Canary and check that + the version of the "Safety Tips" component is updated (you might need to press + the "Check for update" button). + + **Do not check in the full proto**. + +#### In case of emergency + +If the Safety Tips component needs to be disabled immediately, increment the +version number and push an empty proto. +
diff --git a/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py b/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py index a12e8e78..42f3e888 100755 --- a/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py +++ b/chrome/browser/resources/safety_tips/gen_safety_tips_proto.py
@@ -15,6 +15,9 @@ # Subdirectory to be copied to Google Cloud Storage. Contains a copy of the # generated proto under a versioned directory. +# TODO(meacer): Remove this. Safety tips does not read the proto from a local +# resource bundle, it only uses the proto passed from component updater. It does +# not need two copies of the file. GS_COPY_DIR = "gs_copy" # Import the binary proto generator. Walks up to the root of the source tree @@ -45,6 +48,9 @@ assert flagged_page.url assert flagged_page.type != safety_tips_pb2.FlaggedPage.UNKNOWN + flagged_urls = [flagged_page.url for flagged_page in pb.flagged_page] + assert sorted(flagged_urls) == flagged_urls, "Please sort flagged_page entries by URL." + def ProcessPb(self, opts, pb): binary_pb_str = pb.SerializeToString() outfile = os.path.join(opts.outdir, opts.outbasename)
diff --git a/chrome/browser/resources/safety_tips/push_proto.py b/chrome/browser/resources/safety_tips/push_proto.py new file mode 100755 index 0000000..2404cb9 --- /dev/null +++ b/chrome/browser/resources/safety_tips/push_proto.py
@@ -0,0 +1,89 @@ +#!/usr/bin/python +# Copyright 2018 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. + +# Build and push the {vers}/all/ssl_error_assistant.pb file to GCS so +# that the component update system will pick it up and push it to users. +# See README.md before running this. +# +# Requires ninja and gsutil to be in the user's path. + +import optparse +import os +import shutil +import subprocess +import sys + + +DEST_BUCKET = 'gs://chrome-components-safety-tips' +RESOURCE_SUBDIR = 'chrome/browser/resources/safety_tips' + +# Subdirectory to be copied to Google Cloud Storage. Contains a copy of the +# generated proto under a versioned directory. +GS_COPY_DIR = "gs_copy" + +# TODO(meacer): This is pretty much a duplicate of +# chrome/browser/safe_browsing/push_file_type_proto.py. Consider +# refactoring and reusing code. +def main(): + parser = optparse.OptionParser() + parser.add_option('-d', '--dir', + help='An up-to-date GN/Ninja build directory, ' + 'such as ./out/Debug') + + (opts, _) = parser.parse_args() + if opts.dir is None: + parser.print_help() + return 1 + + # Clear out the target dir before we build so we can be sure we've got + # the freshest version. + target_dir = os.path.join(opts.dir, "gen", RESOURCE_SUBDIR) + if os.path.isdir(target_dir): + shutil.rmtree(target_dir) + + gn_command = ['ninja', + '-C', opts.dir, + RESOURCE_SUBDIR + ':make_safety_tips_protobuf'] + print "Running the following" + print " " + (' '.join(gn_command)) + if subprocess.call(gn_command): + print "Ninja failed." + return 1 + + # Use the versioned files under the copy directory to push to the GCS bucket. + copy_dir = os.path.join(target_dir, GS_COPY_DIR) + os.chdir(copy_dir) + + # Sanity check that there is a versioned copy under the directory. + dirs = os.listdir('.') + assert len(dirs) == 1 and dirs[0].isdigit(), ( + "There must be a single versioned dir under " + copy_dir) + + # Push the files with their directories, in the form + # {vers}/{platform}/download_file_types.pb + # Don't overwrite existing files, in case we forgot to increment the + # version. + version_dir = dirs[0] + command = ['gsutil', 'cp', '-Rn', version_dir, DEST_BUCKET] + + print '\nGoing to run the following command' + print ' ', ' '.join(command) + print '\nIn directory' + print ' ', copy_dir + print '\nWhich should push the following files' + expected_files = [os.path.join(dp, f) for dp, _, fn in + os.walk(version_dir) for f in fn] + for f in expected_files: + print ' ', f + + shall = raw_input('\nAre you sure (y/N) ').lower() == 'y' + if not shall: + print 'aborting' + return 1 + return subprocess.call(command) + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/chrome/browser/resources/safety_tips/safety_tips.asciipb b/chrome/browser/resources/safety_tips/safety_tips.asciipb index 9306e6c7..0634d4d 100644 --- a/chrome/browser/resources/safety_tips/safety_tips.asciipb +++ b/chrome/browser/resources/safety_tips/safety_tips.asciipb
@@ -11,6 +11,7 @@ version_id: 1 # See chrome/browser/lookalikes/safety_tips.proto for the full format. +# These entries must be sorted by url. flagged_page { url: "http://example.test/test-path-for-safety-tips/test.html" type: BAD_REP
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index a53102f5..22c9fa9 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc
@@ -46,6 +46,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/startup/startup_browser_creator.h" +#include "chrome/browser/ui/tabs/tab_group_id.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/common/extensions/extension_metrics.h" @@ -440,6 +441,19 @@ RestoreTabsToBrowser(*(*i), browser, initial_tab_count, selected_tab_index, created_contents); + + // Tabs will be grouped appropriately in RestoreTabsToBrowser. Now restore + // the groups' visual data. + if (base::FeatureList::IsEnabled(features::kTabGroups)) { + for (auto& tab_group : (*i)->tab_groups) { + TabGroupVisualData restored_data(std::move(tab_group->title), + tab_group->color); + browser->tab_strip_model()->SetVisualDataForGroup( + TabGroupId::FromRawToken(tab_group->group_id), + std::move(restored_data)); + } + } + NotifySessionServiceOfRestoredTabs(browser, initial_tab_count); // This needs to be done after restore because closing the last tab will // close the whole window.
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index 09831c1..37723c2 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -71,6 +71,7 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "ui/base/page_transition_types.h" #include "ui/base/ui_base_features.h" +#include "ui/gfx/color_palette.h" #if defined(OS_MACOSX) #include "base/mac/scoped_nsautorelease_pool.h" @@ -928,12 +929,37 @@ return result; } +// Building session state from scratch and from an existing browser use +// different code paths. So, create a parametrized test fixture to run each test +// with and without a command reset. The bool test parameter determines whether +// to do a command reset when quitting and restoring. +class SessionRestoreTabGroupsTest : public SessionRestoreTest, + public testing::WithParamInterface<bool> { + protected: + void SetUpOnMainThread() override { + feature_override_.InitAndEnableFeature(features::kTabGroups); + SessionRestoreTest::SetUpOnMainThread(); + } + + Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) { + // The test parameter determines whether to do a command reset. + if (GetParam()) { + SessionService* const session_service = + SessionServiceFactory::GetForProfile(browser->profile()); + session_service->ResetFromCurrentBrowsers(); + } + + return SessionRestoreTest::QuitBrowserAndRestore(browser, + expected_tab_count); + } + + private: + base::test::ScopedFeatureList feature_override_; +}; + } // namespace -IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TabsWithGroups) { - base::test::ScopedFeatureList feature_override; - feature_override.InitAndEnableFeature(features::kTabGroups); - +IN_PROC_BROWSER_TEST_P(SessionRestoreTabGroupsTest, TabsWithGroups) { constexpr int kNumTabs = 6; const std::array<base::Optional<int>, kNumTabs> group_spec = { 0, 0, base::nullopt, base::nullopt, 1, 1}; @@ -957,41 +983,48 @@ EXPECT_EQ(groups, GetTabGroups(new_browser->tab_strip_model())); } -// Test that tab groups are restored correctly after the command set is rebuilt -// from the browser state. -IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TabsWithGroupsCommandReset) { - base::test::ScopedFeatureList feature_override; - feature_override.InitAndEnableFeature(features::kTabGroups); - - constexpr int kNumTabs = 6; - const std::array<base::Optional<int>, kNumTabs> group_spec = { - 0, 0, base::nullopt, base::nullopt, 1, 1}; - - // Open |kNumTabs| tabs. - ui_test_utils::NavigateToURL(browser(), url1_); - for (int i = 1; i < kNumTabs; ++i) { +IN_PROC_BROWSER_TEST_P(SessionRestoreTabGroupsTest, GroupMetadataRestored) { + // Open up 4 more tabs, making 5 including the initial tab. + for (int i = 0; i < 4; ++i) { ui_test_utils::NavigateToURLWithDisposition( browser(), url1_, WindowOpenDisposition::NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); } - ASSERT_EQ(kNumTabs, browser()->tab_strip_model()->count()); - CreateTabGroups(browser()->tab_strip_model(), group_spec); - ASSERT_NO_FATAL_FAILURE( - CheckTabGrouping(browser()->tab_strip_model(), group_spec)); - const auto groups = GetTabGroups(browser()->tab_strip_model()); + TabStripModel* const tsm = browser()->tab_strip_model(); + ASSERT_EQ(5, tsm->count()); - // Rebuild commands. - SessionService* const session_service = - SessionServiceFactory::GetForProfile(browser()->profile()); - ASSERT_TRUE(session_service); - session_service->ResetFromCurrentBrowsers(); + // Group the first 2 and second 2 tabs, making for 2 groups with 2 tabs and 1 + // ungrouped tab in the strip. + const TabGroupId group1 = tsm->AddToNewGroup({0, 1}); + const TabGroupId group2 = tsm->AddToNewGroup({2, 3}); - Browser* new_browser = QuitBrowserAndRestore(browser(), kNumTabs); - ASSERT_EQ(kNumTabs, new_browser->tab_strip_model()->count()); - EXPECT_EQ(groups, GetTabGroups(new_browser->tab_strip_model())); + // Get the default visual data for the first group and set custom visual data + // for the second. + const TabGroupVisualData group1_data = *tsm->GetVisualDataForGroup(group1); + const TabGroupVisualData group2_data(base::ASCIIToUTF16("Foo"), + gfx::kGoogleBlue600); + tsm->SetVisualDataForGroup(group2, group2_data); + + Browser* const new_browser = QuitBrowserAndRestore(browser(), 5); + TabStripModel* const new_tsm = new_browser->tab_strip_model(); + ASSERT_EQ(5, new_tsm->count()); + + // Check that the restored visual data is the same. + const TabGroupVisualData* const group1_restored_data = + new_tsm->GetVisualDataForGroup(group1); + const TabGroupVisualData* const group2_restored_data = + new_tsm->GetVisualDataForGroup(group2); + EXPECT_EQ(group1_data.title(), group1_restored_data->title()); + EXPECT_EQ(group1_data.color(), group1_restored_data->color()); + EXPECT_EQ(group2_data.title(), group2_restored_data->title()); + EXPECT_EQ(group2_data.color(), group2_restored_data->color()); } +INSTANTIATE_TEST_SUITE_P(WithAndWithoutReset, + SessionRestoreTabGroupsTest, + testing::Values(false, true)); + // Ensure tab groups aren't restored if |features::kTabGroups| is disabled. // Regression test for crbug.com/983962. IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
diff --git a/chrome/browser/sessions/session_service.cc b/chrome/browser/sessions/session_service.cc index 112a50f..00875884 100644 --- a/chrome/browser/sessions/session_service.cc +++ b/chrome/browser/sessions/session_service.cc
@@ -200,6 +200,22 @@ ScheduleCommand(sessions::CreateTabGroupCommand(tab_id, group)); } +void SessionService::SetTabGroupMetadata(const SessionID& window_id, + const base::Token& group_id, + const base::string16& title, + SkColor color) { + if (!ShouldTrackChangesToWindow(window_id)) + return; + + // Any group metadata changes happening in a closing window can be ignored. + if (base::Contains(pending_window_close_ids_, window_id) || + base::Contains(window_closing_ids_, window_id)) + return; + + ScheduleCommand( + sessions::CreateTabGroupMetadataUpdateCommand(group_id, title, color)); +} + void SessionService::SetPinnedState(const SessionID& window_id, const SessionID& tab_id, bool is_pinned) { @@ -766,6 +782,14 @@ tab_strip->IsTabPinned(i), tab_to_available_range); } + // Set the visual data for each tab group. + for (const TabGroupId& group_id : tab_strip->ListTabGroups()) { + const TabGroupVisualData* data = tab_strip->GetVisualDataForGroup(group_id); + base_session_service_->AppendRebuildCommand( + sessions::CreateTabGroupMetadataUpdateCommand( + group_id.token(), data->title(), data->color())); + } + base_session_service_->AppendRebuildCommand( sessions::CreateSetSelectedTabInWindowCommand( browser->session_id(),
diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h index 172f18a..a9819e0 100644 --- a/chrome/browser/sessions/session_service.h +++ b/chrome/browser/sessions/session_service.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "base/strings/string16.h" #include "base/task/cancelable_task_tracker.h" #include "base/time/time.h" #include "base/token.h" @@ -27,6 +28,7 @@ #include "components/sessions/core/base_session_service_delegate.h" #include "components/sessions/core/session_service_commands.h" #include "components/sessions/core/tab_restore_service_client.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/ui_base_types.h" class Profile; @@ -125,11 +127,20 @@ const SessionID& tab_id, int new_index); - // Sets a tab's group ID, if any. + // Sets a tab's group ID, if any. Note that a group can't be split between + // multiple windows. void SetTabGroup(const SessionID& window_id, const SessionID& tab_id, base::Optional<base::Token> group); + // Updates the metadata associated with a tab group. |window_id| should be the + // window where the group currently resides. Note that a group can't be split + // between multiple windows. + void SetTabGroupMetadata(const SessionID& window_id, + const base::Token& group_id, + const base::string16& title, + SkColor color); + // Sets the pinned state of the tab. void SetPinnedState(const SessionID& window_id, const SessionID& tab_id,
diff --git a/chrome/browser/sessions/session_service_unittest.cc b/chrome/browser/sessions/session_service_unittest.cc index b88bdd8..01179e6 100644 --- a/chrome/browser/sessions/session_service_unittest.cc +++ b/chrome/browser/sessions/session_service_unittest.cc
@@ -43,6 +43,7 @@ #include "content/public/common/page_state.h" #include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkColor.h" using content::NavigationEntry; using sessions::SerializedNavigationEntry; @@ -1173,13 +1174,14 @@ ASSERT_EQ(1U, windows.size()); ASSERT_EQ(1U, windows[0]->tabs.size()); + ASSERT_EQ(0U, windows[0]->tab_groups.size()); // Verify that the recorded tab has no group. sessions::SessionTab* tab = windows[0]->tabs[0].get(); EXPECT_EQ(base::nullopt, tab->group); } -TEST_F(SessionServiceTest, TabGroupIdsSaved) { +TEST_F(SessionServiceTest, TabGroupsSaved) { const auto group1_token = base::Token::CreateRandom(); const auto group2_token = base::Token::CreateRandom(); constexpr int kNumTabs = 5; @@ -1198,6 +1200,7 @@ ASSERT_EQ(1U, windows.size()); ASSERT_EQ(kNumTabs, static_cast<int>(windows[0]->tabs.size())); + ASSERT_EQ(2U, windows[0]->tab_groups.size()); for (int tab_ndx = 0; tab_ndx < kNumTabs; ++tab_ndx) { sessions::SessionTab* tab = windows[0]->tabs[tab_ndx].get(); @@ -1205,6 +1208,45 @@ } } +TEST_F(SessionServiceTest, TabGroupMetadataSaved) { + constexpr int kNumGroups = 2; + const std::array<base::Token, kNumGroups> group_ids = { + base::Token::CreateRandom(), base::Token::CreateRandom()}; + const std::array<base::string16, kNumGroups> titles = { + base::ASCIIToUTF16("Foo"), base::ASCIIToUTF16("Bar")}; + const std::array<SkColor, kNumGroups> colors = {SK_ColorBLUE, SK_ColorGREEN}; + + // Create |kNumGroups| tab groups, each with one tab. + for (int group_ndx = 0; group_ndx < kNumGroups; ++group_ndx) { + const SessionID tab_id = + CreateTabWithTestNavigationData(window_id, group_ndx); + service()->SetTabGroup(window_id, tab_id, group_ids[group_ndx]); + service()->SetTabGroupMetadata(window_id, group_ids[group_ndx], + titles[group_ndx], colors[group_ndx]); + } + + std::vector<std::unique_ptr<sessions::SessionWindow>> windows; + ReadWindows(&windows, nullptr); + + ASSERT_EQ(1U, windows.size()); + ASSERT_EQ(2U, windows[0]->tabs.size()); + ASSERT_EQ(2U, windows[0]->tab_groups.size()); + + // There's no guaranteed order in |SessionWindow::tab_groups|, so use a map. + base::flat_map<base::Token, sessions::SessionTabGroup*> tab_groups; + for (int group_ndx = 0; group_ndx < kNumGroups; ++group_ndx) { + tab_groups.emplace(windows[0]->tab_groups[group_ndx]->group_id, + windows[0]->tab_groups[group_ndx].get()); + } + + for (int group_ndx = 0; group_ndx < kNumGroups; ++group_ndx) { + const base::Token group_id = group_ids[group_ndx]; + ASSERT_TRUE(base::Contains(tab_groups, group_id)); + EXPECT_EQ(titles[group_ndx], tab_groups[group_id]->title); + EXPECT_EQ(colors[group_ndx], tab_groups[group_id]->color); + } +} + // Functions used by GetSessionsAndDestroy. namespace {
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc index 1037b94..f683792 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc +++ b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h" +#include <utility> + #include "base/strings/strcat.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/external_protocol/external_protocol_handler.h" @@ -46,10 +48,8 @@ // Invalidate old dialog results. controller->last_dialog_id_++; controller->phone_url_ = url; - controller->is_loading_ = false; - controller->send_failed_ = false; controller->hide_default_handler_ = hide_default_handler; - controller->ShowNewDialog(); + controller->InvalidateOldDialog(); } // static @@ -66,7 +66,7 @@ ClickToCallSharingDialogController::ClickToCallSharingDialogController( content::WebContents* web_contents) - : web_contents_(web_contents), + : SharingDialogController(web_contents), sharing_service_(SharingServiceFactory::GetForBrowserContext( web_contents->GetBrowserContext())) {} @@ -78,42 +78,6 @@ IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TITLE_LABEL); } -void ClickToCallSharingDialogController::ShowNewDialog() { - if (dialog_) - dialog_->Hide(); - - // Treat the dialog as closed as the process of closing the native widget - // might be async. - dialog_ = nullptr; - - Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); - auto* window = browser ? browser->window() : nullptr; - if (!window) - return; - - dialog_ = window->ShowClickToCallDialog(web_contents_, this); - UpdateIcon(); -} - -void ClickToCallSharingDialogController::ShowErrorDialog() { - Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); - if (!browser) - return; - - if (web_contents_ == browser->tab_strip_model()->GetActiveWebContents()) - ShowNewDialog(); -} - -void ClickToCallSharingDialogController::UpdateIcon() { - Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); - auto* window = browser ? browser->window() : nullptr; - if (!window) - return; - - auto* icon_container = window->GetOmniboxPageActionIconContainer(); - if (icon_container) - icon_container->UpdatePageActionIcon(PageActionIconType::kClickToCall); -} std::vector<SharingDeviceInfo> ClickToCallSharingDialogController::GetSyncedDevices() { @@ -138,9 +102,7 @@ void ClickToCallSharingDialogController::OnDeviceChosen( const SharingDeviceInfo& device) { - is_loading_ = true; - send_failed_ = false; - UpdateIcon(); + StartLoading(); std::string phone_number_string(phone_url_.GetContent()); url::RawCanonOutputT<base::char16> unescaped_phone_number; @@ -164,35 +126,26 @@ if (dialog_id != last_dialog_id_) return; - is_loading_ = false; - send_failed_ = !success; - UpdateIcon(); - - if (!success) - ShowErrorDialog(); + StopLoading(!success); } void ClickToCallSharingDialogController::OnAppChosen(const App& app) { ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck(phone_url_, - web_contents_); -} - -void ClickToCallSharingDialogController::OnDialogClosed(SharingDialog* dialog) { - // Ignore already replaced dialogs. - if (dialog != dialog_) - return; - - dialog_ = nullptr; - UpdateIcon(); + web_contents()); } void ClickToCallSharingDialogController::OnHelpTextClicked() { - ShowSingletonTab(chrome::FindBrowserWithWebContents(web_contents_), + ShowSingletonTab(chrome::FindBrowserWithWebContents(web_contents()), GURL(chrome::kSyncLearnMoreURL)); } -SharingDialog* ClickToCallSharingDialogController::GetDialog() const { - return dialog_; +SharingDialog* ClickToCallSharingDialogController::DoShowDialog( + BrowserWindow* window) { + return window->ShowClickToCallDialog(web_contents_, this); +} + +PageActionIconType ClickToCallSharingDialogController::GetIconType() { + return PageActionIconType::kClickToCall; } WEB_CONTENTS_USER_DATA_KEY_IMPL(ClickToCallSharingDialogController)
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h index 57fcab3..e885ab94 100644 --- a/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h +++ b/chrome/browser/sharing/click_to_call/click_to_call_sharing_dialog_controller.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/sharing/sharing_dialog_controller.h" #include "chrome/browser/sharing/sharing_service.h" +#include "chrome/browser/ui/page_action/page_action_icon_container.h" #include "content/public/browser/web_contents_user_data.h" #include "url/gurl.h" @@ -19,7 +20,6 @@ class WebContents; } // namespace content -class SharingDialog; class SharingDeviceInfo; class ClickToCallSharingDialogController @@ -43,24 +43,15 @@ std::vector<App> GetApps() override; void OnDeviceChosen(const SharingDeviceInfo& device) override; void OnAppChosen(const App& app) override; - - // Called by the ClickToCallDialogView when it is being closed. - void OnDialogClosed(SharingDialog* dialog); + PageActionIconType GetIconType() override; // Called by the ClickToCallDialogView when the help text got clicked. void OnHelpTextClicked(); - // Returns the currently open ClickToCallDialog or nullptr if there is no - // dialog open. - SharingDialog* GetDialog() const; - - bool is_loading() const { return is_loading_; } - - bool send_failed() const { return send_failed_; } - protected: explicit ClickToCallSharingDialogController( content::WebContents* web_contents); + SharingDialog* DoShowDialog(BrowserWindow* window) override; private: friend class content::WebContentsUserData<ClickToCallSharingDialogController>; @@ -69,25 +60,14 @@ // |success| is false and updates the omnibox icon. void OnMessageSentToDevice(int dialog_id, bool success); - // Shows a new ClickToCallDialogView and closes the old one. - void ShowNewDialog(); - - // Shows an error dialog if we're still on the same tab. - void ShowErrorDialog(); - - // Updates the omnibox icon if available. - void UpdateIcon(); - content::WebContents* web_contents_ = nullptr; SharingService* sharing_service_ = nullptr; GURL phone_url_; - SharingDialog* dialog_ = nullptr; - bool is_loading_ = false; - bool send_failed_ = false; bool hide_default_handler_ = false; // ID of the last shown dialog used to ignore events from old dialogs. + // TODO(yasmo): Maybe can be moved to the base class. int last_dialog_id_ = 0; base::WeakPtrFactory<ClickToCallSharingDialogController> weak_ptr_factory_{
diff --git a/chrome/browser/sharing/sharing_dialog_controller.cc b/chrome/browser/sharing/sharing_dialog_controller.cc index cf46895..69b9c5d 100644 --- a/chrome/browser/sharing/sharing_dialog_controller.cc +++ b/chrome/browser/sharing/sharing_dialog_controller.cc
@@ -4,6 +4,12 @@ #include "chrome/browser/sharing/sharing_dialog_controller.h" +#include <utility> + +#include "chrome/browser/sharing/sharing_dialog.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_window.h" + SharingDialogController::App::App(const gfx::VectorIcon& icon, base::string16 name, std::string identifier) @@ -12,3 +18,74 @@ SharingDialogController::App::App(App&& other) = default; SharingDialogController::App::~App() = default; + +SharingDialogController::SharingDialogController( + content::WebContents* web_contents) + : web_contents_(web_contents) {} + +void SharingDialogController::ShowNewDialog() { + if (dialog_) + dialog_->Hide(); + + // Treat the dialog as closed as the process of closing the native widget + // might be async. + dialog_ = nullptr; + + Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); + auto* window = browser ? browser->window() : nullptr; + if (!window) + return; + + dialog_ = DoShowDialog(window); + UpdateIcon(); +} + +void SharingDialogController::UpdateIcon() { + Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); + auto* window = browser ? browser->window() : nullptr; + if (!window) + return; + + auto* icon_container = window->GetOmniboxPageActionIconContainer(); + if (icon_container) + icon_container->UpdatePageActionIcon(GetIconType()); +} + +void SharingDialogController::OnDialogClosed(SharingDialog* dialog) { + // Ignore already replaced dialogs. + if (dialog != dialog_) + return; + + dialog_ = nullptr; + UpdateIcon(); +} + +void SharingDialogController::ShowErrorDialog() { + Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); + if (!browser) + return; + + if (web_contents_ == browser->tab_strip_model()->GetActiveWebContents()) + ShowNewDialog(); +} + +void SharingDialogController::StartLoading() { + is_loading_ = true; + send_failed_ = false; + UpdateIcon(); +} + +void SharingDialogController::StopLoading(bool send_failed) { + is_loading_ = false; + send_failed_ = send_failed; + UpdateIcon(); + + if (send_failed) + ShowErrorDialog(); +} + +void SharingDialogController::InvalidateOldDialog() { + is_loading_ = false; + send_failed_ = false; + ShowNewDialog(); +}
diff --git a/chrome/browser/sharing/sharing_dialog_controller.h b/chrome/browser/sharing/sharing_dialog_controller.h index fbcf69e..9f5121e 100644 --- a/chrome/browser/sharing/sharing_dialog_controller.h +++ b/chrome/browser/sharing/sharing_dialog_controller.h
@@ -10,13 +10,20 @@ #include "base/macros.h" #include "base/strings/string16.h" +#include "chrome/browser/ui/page_action/page_action_icon_container.h" +class BrowserWindow; class SharingDeviceInfo; +class SharingDialog; namespace gfx { struct VectorIcon; } // namespace gfx +namespace content { +class WebContents; +} // namespace content + // The controller for desktop dialog with the list of synced devices and apps. class SharingDialogController { public: @@ -32,7 +39,7 @@ std::string identifier; }; - SharingDialogController() = default; + explicit SharingDialogController(content::WebContents* web_contents); virtual ~SharingDialogController() = default; // Title of the dialog. @@ -49,6 +56,36 @@ // Called when user chooses a local app to complete the task. virtual void OnAppChosen(const App& app) = 0; + + virtual PageActionIconType GetIconType() = 0; + + // Called by the ClickToCallDialogView when it is being closed. + void OnDialogClosed(SharingDialog* dialog); + void StartLoading(); + void StopLoading(bool send_failed); + void InvalidateOldDialog(); + // Shows an error dialog if we're still on the same tab. + void ShowErrorDialog(); + // Returns the currently open SharingDialog or nullptr if there is no + // dialog open. + SharingDialog* dialog() const { return dialog_; } + bool is_loading() const { return is_loading_; } + bool send_failed() const { return send_failed_; } + content::WebContents* web_contents() const { return web_contents_; } + + protected: + virtual SharingDialog* DoShowDialog(BrowserWindow* window) = 0; + + private: + // Updates the omnibox icon if available. + void UpdateIcon(); + // Shows a new ClickToCallDialogView and closes the old one. + void ShowNewDialog(); + + SharingDialog* dialog_ = nullptr; + bool is_loading_ = false; + bool send_failed_ = false; + content::WebContents* web_contents_ = nullptr; }; #endif // CHROME_BROWSER_SHARING_SHARING_DIALOG_CONTROLLER_H_
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc index 46bf598..d59b982c 100644 --- a/chrome/browser/shell_integration_win.cc +++ b/chrome/browser/shell_integration_win.cc
@@ -725,8 +725,8 @@ return; } - base::CreateCOMSTATaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::BEST_EFFORT}) + base::CreateCOMSTATaskRunner( + {base::ThreadPool(), base::MayBlock(), base::TaskPriority::BEST_EFFORT}) ->PostTask(FROM_HERE, base::BindOnce(&MigrateTaskbarPinsCallback, taskbar_path, implicit_apps_path)); }
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index f271b01..76036ce8 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" @@ -63,6 +64,19 @@ } } +security_state::SafetyTipStatus GetSecurityStateSafetyTipType( + safety_tips::SafetyTipType type) { + switch (type) { + case safety_tips::SafetyTipType::kNone: + return security_state::SafetyTipStatus::SAFETY_TIP_STATUS_NONE; + case safety_tips::SafetyTipType::kBadReputation: + return security_state::SafetyTipStatus::SAFETY_TIP_STATUS_BAD_REPUTATION; + default: + NOTREACHED(); + return security_state::SafetyTipStatus::SAFETY_TIP_STATUS_NONE; + } +} + } // namespace using password_manager::metrics_util::PasswordType; @@ -88,6 +102,14 @@ // information is still being initialized, thus no need to check for that. state->malicious_content_status = GetMaliciousContentStatus(); + safety_tips::ReputationWebContentsObserver* reputation_web_contents_observer = + safety_tips::ReputationWebContentsObserver::FromWebContents( + web_contents()); + state->safety_tip_status = + reputation_web_contents_observer + ? GetSecurityStateSafetyTipType( + reputation_web_contents_observer->last_shown_safety_tip_type()) + : security_state::SafetyTipStatus::SAFETY_TIP_STATUS_NONE; return state; }
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index 12fbbbac..6236fa90 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -46,6 +46,7 @@ #include "chrome/common/channel_info.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/common/autofill_features.h" +#include "components/browser_sync/browser_sync_switches.h" #include "components/invalidation/impl/invalidation_switches.h" #include "components/invalidation/impl/profile_identity_provider.h" #include "components/invalidation/impl/profile_invalidation_provider.h" @@ -261,7 +262,12 @@ // intervention). We can get rid of the browser_default eventually, but // need to take care that ProfileSyncService doesn't get tripped up between // those two cases. Bug 88109. - init_params.start_behavior = browser_defaults::kSyncAutoStarts + bool is_auto_start = browser_defaults::kSyncAutoStarts; +#if defined(OS_ANDROID) + if (base::FeatureList::IsEnabled(switches::kSyncManualStartAndroid)) + is_auto_start = false; +#endif + init_params.start_behavior = is_auto_start ? syncer::ProfileSyncService::AUTO_START : syncer::ProfileSyncService::MANUAL_START; }
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 17f680a..8da7549 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1067,6 +1067,19 @@ selection.new_model.active(), selection.reason); } +void Browser::OnTabGroupVisualDataChanged( + TabStripModel* tab_strip_model, + TabGroupId group, + const TabGroupVisualData* visual_data) { + SessionService* const session_service = + SessionServiceFactory::GetForProfile(profile_); + if (session_service) { + session_service->SetTabGroupMetadata(session_id(), group.token(), + visual_data->title(), + visual_data->color()); + } +} + void Browser::TabPinnedStateChanged(TabStripModel* tab_strip_model, WebContents* contents, int index) {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index c4ac889..df292eaf 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -509,6 +509,10 @@ TabStripModel* tab_strip_model, const TabStripModelChange& change, const TabStripSelectionChange& selection) override; + void OnTabGroupVisualDataChanged( + TabStripModel* tab_strip_model, + TabGroupId group, + const TabGroupVisualData* visual_data) override; void TabPinnedStateChanged(TabStripModel* tab_strip_model, content::WebContents* contents, int index) override;
diff --git a/chrome/browser/ui/global_media_controls/media_dialog_controller.cc b/chrome/browser/ui/global_media_controls/media_dialog_controller.cc index b939b741..a60816f 100644 --- a/chrome/browser/ui/global_media_controls/media_dialog_controller.cc +++ b/chrome/browser/ui/global_media_controls/media_dialog_controller.cc
@@ -47,7 +47,10 @@ media_session::mojom::AudioFocusRequestStatePtr session) { const std::string id = session->request_id->ToString(); - if (base::Contains(sessions_, id)) + // If we have an existing unfrozen item then this is a duplicate call and + // we should ignore it. + auto it = sessions_.find(id); + if (it != sessions_.end() && !it->second.frozen()) return; media_session::mojom::MediaControllerPtr controller; @@ -59,16 +62,27 @@ mojo::MakeRequest(&controller), *session->request_id); } - sessions_.emplace( - std::piecewise_construct, std::forward_as_tuple(id), - std::forward_as_tuple( - this, id, session->source_name.value_or(std::string()), - std::move(controller), std::move(session->session_info))); + if (it != sessions_.end()) { + // If the notification was previously frozen then we should reset the + // controller because the mojo pipe would have been reset. + it->second.SetController(std::move(controller), + std::move(session->session_info)); + } else { + sessions_.emplace( + std::piecewise_construct, std::forward_as_tuple(id), + std::forward_as_tuple( + this, id, session->source_name.value_or(std::string()), + std::move(controller), std::move(session->session_info))); + } } void MediaDialogController::OnFocusLost( media_session::mojom::AudioFocusRequestStatePtr session) { - sessions_.erase(session->request_id->ToString()); + auto it = sessions_.find(session->request_id->ToString()); + if (it == sessions_.end()) + return; + + it->second.Freeze(); } void MediaDialogController::ShowNotification(const std::string& id) { @@ -85,6 +99,15 @@ delegate_->HideMediaSession(id); } +void MediaDialogController::RemoveItem(const std::string& id) { + sessions_.erase(id); +} + +scoped_refptr<base::SequencedTaskRunner> MediaDialogController::GetTaskRunner() + const { + return task_runner_for_testing_; +} + void MediaDialogController::OnReceivedAudioFocusRequests( std::vector<media_session::mojom::AudioFocusRequestStatePtr> sessions) { for (auto& session : sessions)
diff --git a/chrome/browser/ui/global_media_controls/media_dialog_controller.h b/chrome/browser/ui/global_media_controls/media_dialog_controller.h index f6d9a9d..22ed04e0b 100644 --- a/chrome/browser/ui/global_media_controls/media_dialog_controller.h +++ b/chrome/browser/ui/global_media_controls/media_dialog_controller.h
@@ -45,6 +45,8 @@ // media_message_center::MediaNotificationController implementation. void ShowNotification(const std::string& id) override; void HideNotification(const std::string& id) override; + void RemoveItem(const std::string& id) override; + scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override; private: friend class MediaDialogControllerTest; @@ -69,6 +71,9 @@ mojo::Receiver<media_session::mojom::AudioFocusObserver> audio_focus_observer_receiver_{this}; + // Task runner used for testing. + scoped_refptr<base::SequencedTaskRunner> task_runner_for_testing_; + base::WeakPtrFactory<MediaDialogController> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(MediaDialogController);
diff --git a/chrome/browser/ui/global_media_controls/media_dialog_controller_unittest.cc b/chrome/browser/ui/global_media_controls/media_dialog_controller_unittest.cc index e9e6fa9..54c6acab 100644 --- a/chrome/browser/ui/global_media_controls/media_dialog_controller_unittest.cc +++ b/chrome/browser/ui/global_media_controls/media_dialog_controller_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/strings/utf_string_conversions.h" +#include "base/test/test_mock_time_task_runner.h" #include "base/unguessable_token.h" #include "chrome/browser/ui/global_media_controls/media_dialog_controller_delegate.h" #include "components/media_message_center/media_notification_item.h" @@ -40,11 +41,15 @@ class MediaDialogControllerTest : public testing::Test { public: - MediaDialogControllerTest() = default; + MediaDialogControllerTest() + : task_runner_(new base::TestMockTimeTaskRunner( + base::TestMockTimeTaskRunner::Type::kStandalone)) {} + ~MediaDialogControllerTest() override = default; void SetUp() override { controller_ = std::make_unique<MediaDialogController>(nullptr, &delegate_); + controller_->task_runner_for_testing_ = task_runner_.get(); } protected: @@ -91,9 +96,21 @@ controller_->OnReceivedAudioFocusRequests(std::move(requests)); } + void SimulateFreezeTimerExpired() { + task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(2500)); + } + + bool IsSessionFrozen(const base::UnguessableToken& id) const { + auto item_itr = controller_->sessions_.find(id.ToString()); + EXPECT_NE(controller_->sessions_.end(), item_itr); + return item_itr->second.frozen(); + } + MockMediaDialogControllerDelegate& delegate() { return delegate_; } private: + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; + MockMediaDialogControllerDelegate delegate_; std::unique_ptr<MediaDialogController> controller_; @@ -107,12 +124,20 @@ SimulateFocusGained(id, true); SimulateNecessaryMetadata(id); + EXPECT_FALSE(IsSessionFrozen(id)); // Ensure that the session was shown. testing::Mock::VerifyAndClearExpectations(&delegate()); - EXPECT_CALL(delegate(), HideMediaSession(id.ToString())); + EXPECT_CALL(delegate(), HideMediaSession(id.ToString())).Times(0); SimulateFocusLost(id); + EXPECT_TRUE(IsSessionFrozen(id)); + + // Ensure that the session was not hidden. + testing::Mock::VerifyAndClearExpectations(&delegate()); + + EXPECT_CALL(delegate(), HideMediaSession(id.ToString())); + SimulateFreezeTimerExpired(); } TEST_F(MediaDialogControllerTest, DoesNotShowUncontrollableSession) {
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index b0c14e4..be73c58 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -332,6 +332,7 @@ site_url_(url), site_identity_status_(SITE_IDENTITY_STATUS_UNKNOWN), safe_browsing_status_(SAFE_BROWSING_STATUS_NONE), + safety_tip_status_(security_state::SAFETY_TIP_STATUS_NONE), site_connection_status_(SITE_CONNECTION_STATUS_UNKNOWN), show_ssl_decision_revoke_button_(false), content_settings_(HostContentSettingsMapFactory::GetForProfile(profile)), @@ -763,6 +764,13 @@ #endif } + if (visible_security_state.safety_tip_status != + security_state::SAFETY_TIP_STATUS_NONE) { + site_details_message_ = l10n_util::GetStringUTF16( + IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_DESCRIPTION); + safety_tip_status_ = visible_security_state.safety_tip_status; + } + // Site Connection // We consider anything less than 80 bits encryption to be weak encryption. // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and @@ -971,6 +979,7 @@ info.connection_status_description = UTF16ToUTF8(site_connection_details_); info.identity_status = site_identity_status_; info.safe_browsing_status = safe_browsing_status_; + info.safety_tip_status = safety_tip_status_; info.identity_status_description = UTF16ToUTF8(site_details_message_); info.certificate = certificate_; info.show_ssl_decision_revoke_button = show_ssl_decision_revoke_button_;
diff --git a/chrome/browser/ui/page_info/page_info.h b/chrome/browser/ui/page_info/page_info.h index 25dc0e2..f570ed6 100644 --- a/chrome/browser/ui/page_info/page_info.h +++ b/chrome/browser/ui/page_info/page_info.h
@@ -274,6 +274,9 @@ // Safe Browsing status of the website. SafeBrowsingStatus safe_browsing_status_; + // Safety tip status of the website. + security_state::SafetyTipStatus safety_tip_status_; + // For secure connection |certificate_| is set to the server certificate. scoped_refptr<net::X509Certificate> certificate_;
diff --git a/chrome/browser/ui/page_info/page_info_ui.cc b/chrome/browser/ui/page_info/page_info_ui.cc index ffd5b70..340f335e 100644 --- a/chrome/browser/ui/page_info/page_info_ui.cc +++ b/chrome/browser/ui/page_info/page_info_ui.cc
@@ -235,6 +235,7 @@ PageInfoUI::IdentityInfo::IdentityInfo() : identity_status(PageInfo::SITE_IDENTITY_STATUS_UNKNOWN), safe_browsing_status(PageInfo::SAFE_BROWSING_STATUS_NONE), + safety_tip_status(security_state::SAFETY_TIP_STATUS_NONE), connection_status(PageInfo::SITE_CONNECTION_STATUS_UNKNOWN), show_ssl_decision_revoke_button(false), show_change_password_buttons(false) {} @@ -284,6 +285,13 @@ IDS_PAGE_INFO_BILLING_DETAILS); } + if (identity_info.safety_tip_status == + security_state::SAFETY_TIP_STATUS_BAD_REPUTATION) { + return CreateSecurityDescription( + SecuritySummaryColor::RED, IDS_PAGE_INFO_SAFETY_TIP_SUMMARY, + IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_DESCRIPTION); + } + switch (identity_info.identity_status) { case PageInfo::SITE_IDENTITY_STATUS_INTERNAL_PAGE: #if defined(OS_ANDROID)
diff --git a/chrome/browser/ui/page_info/page_info_ui.h b/chrome/browser/ui/page_info/page_info_ui.h index 6f96254..734c633 100644 --- a/chrome/browser/ui/page_info/page_info_ui.h +++ b/chrome/browser/ui/page_info/page_info_ui.h
@@ -112,6 +112,8 @@ PageInfo::SiteIdentityStatus identity_status; // Site's Safe Browsing status. PageInfo::SafeBrowsingStatus safe_browsing_status; + // Site's safety tip status. + security_state::SafetyTipStatus safety_tip_status; // Textual description of the site's identity status that is displayed to // the user. std::string identity_status_description;
diff --git a/chrome/browser/ui/views/chrome_web_dialog_view.cc b/chrome/browser/ui/views/chrome_web_dialog_view.cc index ef11e5a4..8e5c87ff 100644 --- a/chrome/browser/ui/views/chrome_web_dialog_view.cc +++ b/chrome/browser/ui/views/chrome_web_dialog_view.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/webui/chrome_web_contents_handler.h" #include "ui/views/controls/webview/web_dialog_view.h" #include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_delegate.h" #if defined(OS_CHROMEOS) #include "ash/public/cpp/multi_user_window_manager.h" @@ -83,4 +84,32 @@ return window; } +gfx::NativeWindow ShowWebDialogWithBounds(gfx::NativeView parent, + content::BrowserContext* context, + ui::WebDialogDelegate* delegate, + const gfx::Rect& bounds) { + // Use custom dialog frame instead of platform frame when possible. + bool use_dialog_frame = views::DialogDelegate::CanSupportCustomFrame(parent); + views::WebDialogView* view = new views::WebDialogView( + context, delegate, std::make_unique<ChromeWebContentsHandler>(), + use_dialog_frame); + + views::Widget::InitParams params; + params.delegate = view; + params.bounds = bounds; + params.parent = parent; + if (use_dialog_frame) { + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.remove_standard_frame = true; +#if !defined(OS_MACOSX) + // Except on Mac, the bubble frame includes its own shadow; remove any + // native shadowing. On Mac, the window server provides the shadow. + params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; +#endif + } + + gfx::NativeWindow window = ShowWebDialogWidget(std::move(params), view); + return window; +} + } // namespace chrome
diff --git a/chrome/browser/ui/views/chrome_web_dialog_view.h b/chrome/browser/ui/views/chrome_web_dialog_view.h index ca99a5a..04dccca 100644 --- a/chrome/browser/ui/views/chrome_web_dialog_view.h +++ b/chrome/browser/ui/views/chrome_web_dialog_view.h
@@ -26,6 +26,15 @@ ui::WebDialogDelegate* delegate, base::Optional<views::Widget::InitParams> extra_params); +// The implementation is more aligned with the appearance of constrained +// web dialog. +// TODO(weili): Solely use this function on non-ChromeOS platform, and +// above ShowWebDialogWithParams() on ChromeOS. Or merge these two if possible. +gfx::NativeWindow ShowWebDialogWithBounds(gfx::NativeView parent, + content::BrowserContext* context, + ui::WebDialogDelegate* delegate, + const gfx::Rect& bounds); + } // namespace chrome #endif // CHROME_BROWSER_UI_VIEWS_CHROME_WEB_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc index 9f1a4f0..c2a8e91 100644 --- a/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_toolbar_button_view.cc
@@ -6,7 +6,9 @@ #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/views/global_media_controls/media_dialog_view.h" +#include "chrome/grit/generated_resources.h" #include "components/vector_icons/vector_icons.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/theme_provider.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/native_theme/native_theme.h" @@ -20,6 +22,9 @@ button_controller()->set_notify_action( views::ButtonController::NotifyAction::NOTIFY_ON_PRESS); EnableCanvasFlippingForRTLUI(false); + SetTooltipText( + l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT)); + ToolbarButton::Init(); // We start hidden and only show once |controller_| tells us to.
diff --git a/chrome/browser/ui/views/hats/hats_web_dialog.cc b/chrome/browser/ui/views/hats/hats_web_dialog.cc index eb0af7d..e3eb17d3 100644 --- a/chrome/browser/ui/views/hats/hats_web_dialog.cc +++ b/chrome/browser/ui/views/hats/hats_web_dialog.cc
@@ -27,8 +27,8 @@ namespace { // Default width/height of the dialog in screen size. -const int kDefaultHatsDialogWidth = 400; -const int kDefaultHatsDialogHeight = 420; +const int kDefaultHatsDialogWidth = 448; +const int kDefaultHatsDialogHeight = 440; // Placeholder strings in html file to be replaced when the file is loaded. constexpr char kScriptSrcReplacementToken[] = "$SCRIPT_SRC"; @@ -84,15 +84,13 @@ DCHECK(location_bar); gfx::Rect bounds(location_bar->bounds()); views::View::ConvertRectToScreen(browser_view->toolbar(), &bounds); - views::Widget::InitParams params; - params.bounds = gfx::Rect( + bounds = gfx::Rect( bounds.x() + std::max(0, bounds.width() / 2 - kDefaultHatsDialogWidth / 2), bounds.bottom() - views::BubbleBorder::GetBorderAndShadowInsets().top(), kDefaultHatsDialogWidth, kDefaultHatsDialogHeight); - chrome::ShowWebDialogWithParams( - browser_view->GetWidget()->GetNativeView(), profile, hats_dialog, - base::make_optional<views::Widget::InitParams>(std::move(params))); + chrome::ShowWebDialogWithBounds(browser_view->GetWidget()->GetNativeView(), + profile, hats_dialog, bounds); } HatsWebDialog::HatsWebDialog(const std::string& site_id) : site_id_(site_id) {
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc index 984acaa..c9ee0354 100644 --- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view_browsertest.cc
@@ -10,17 +10,22 @@ #include "chrome/browser/lookalikes/safety_tips/reputation_web_contents_observer.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/location_bar/location_icon_view.h" #include "chrome/browser/ui/views/page_info/page_info_bubble_view_base.h" #include "chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.h" +#include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_navigation_observer.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "ui/accessibility/ax_action_data.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/views/test/widget_test.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_observer.h" @@ -33,6 +38,11 @@ // An engagement score below MEDIUM. const int kLowEngagement = 1; +class ClickEvent : public ui::Event { + public: + ClickEvent() : ui::Event(ui::ET_UNKNOWN, base::TimeTicks(), 0) {} +}; + // Simulates a link click navigation. We don't use // ui_test_utils::NavigateToURL(const GURL&) because it simulates the user // typing the URL, causing the site to have a site engagement score of at @@ -84,6 +94,38 @@ NavigateToURLSync(browser, navigated_url); } +// Clicks the location icon to open the page info bubble. +void OpenPageInfoBubble(Browser* browser) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + LocationIconView* location_icon_view = + browser_view->toolbar()->location_bar()->location_icon_view(); + ASSERT_TRUE(location_icon_view); + ClickEvent event; + location_icon_view->ShowBubble(event); + views::BubbleDialogDelegateView* page_info = + PageInfoBubbleViewBase::GetPageInfoBubble(); + EXPECT_NE(nullptr, page_info); + page_info->set_close_on_deactivate(false); +} + +void CheckPageInfoShowsSafetyTipInfo(Browser* browser) { + OpenPageInfoBubble(browser); + views::BubbleDialogDelegateView* page_info = + PageInfoBubbleViewBase::GetPageInfoBubble(); + CHECK(page_info); + EXPECT_EQ(page_info->GetWindowTitle(), + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SAFETY_TIP_SUMMARY)); +} + +void CheckPageInfoDoesNotShowSafetyTipInfo(Browser* browser) { + OpenPageInfoBubble(browser); + views::BubbleDialogDelegateView* page_info = + PageInfoBubbleViewBase::GetPageInfoBubble(); + CHECK(page_info); + EXPECT_NE(page_info->GetWindowTitle(), + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SAFETY_TIP_SUMMARY)); +} + } // namespace class SafetyTipPageInfoBubbleViewBrowserTest : public InProcessBrowserTest { @@ -132,6 +174,8 @@ SetEngagementScore(browser(), kNavigatedUrl, kHighEngagement); NavigateToURLSync(browser(), kNavigatedUrl); EXPECT_FALSE(IsUIShowing()); + + CheckPageInfoDoesNotShowSafetyTipInfo(browser()); } // Until we have heuristics, trigger on all low engagement sites. @@ -141,6 +185,8 @@ SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement); NavigateToURLSync(browser(), kNavigatedUrl); EXPECT_TRUE(IsUIShowing()); + + CheckPageInfoShowsSafetyTipInfo(browser()); } // After the user clicks 'leave site', the user should end up on a safe domain. @@ -153,6 +199,8 @@ EXPECT_FALSE(IsUIShowing()); EXPECT_NE(kNavigatedUrl, browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + CheckPageInfoDoesNotShowSafetyTipInfo(browser()); } // If the user clicks 'leave site', the warning should re-appear when the user @@ -169,6 +217,8 @@ EXPECT_TRUE(IsUIShowing()); EXPECT_EQ(kNavigatedUrl, browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + CheckPageInfoShowsSafetyTipInfo(browser()); } // After the user closes the warning, they should still be on the same domain. @@ -181,6 +231,8 @@ EXPECT_FALSE(IsUIShowing()); EXPECT_EQ(kNavigatedUrl, browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + CheckPageInfoShowsSafetyTipInfo(browser()); } // If the user closes the bubble, the warning should not re-appear when the user @@ -197,4 +249,22 @@ EXPECT_FALSE(IsUIShowing()); EXPECT_EQ(kNavigatedUrl, browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); + + CheckPageInfoDoesNotShowSafetyTipInfo(browser()); +} + +// Non main-frame navigations should be ignored. +IN_PROC_BROWSER_TEST_F(SafetyTipPageInfoBubbleViewBrowserTest, + IgnoreIFrameNavigations) { + const GURL kNavigatedUrl = + embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html"); + const GURL kFrameUrl = + embedded_test_server()->GetURL("b.com", "/title1.html"); + SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement); + SetEngagementScore(browser(), kFrameUrl, kHighEngagement); + + NavigateToURLSync(browser(), kNavigatedUrl); + EXPECT_TRUE(IsUIShowing()); + + CheckPageInfoShowsSafetyTipInfo(browser()); }
diff --git a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc index f1a371eb..6071ca5 100644 --- a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc +++ b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.cc
@@ -25,9 +25,8 @@ PasswordAutoSignInView::PasswordAutoSignInView( content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason) - : PasswordBubbleViewBase(web_contents, anchor_view, anchor_point, reason) { + : PasswordBubbleViewBase(web_contents, anchor_view, reason) { SetLayoutManager(std::make_unique<views::FillLayout>()); const autofill::PasswordForm& form = model()->pending_password();
diff --git a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.h b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.h index 8b603dd7..e2ea5d14 100644 --- a/chrome/browser/ui/views/passwords/password_auto_sign_in_view.h +++ b/chrome/browser/ui/views/passwords/password_auto_sign_in_view.h
@@ -17,10 +17,9 @@ class PasswordAutoSignInView : public PasswordBubbleViewBase, public views::ButtonListener { public: - explicit PasswordAutoSignInView(content::WebContents* web_contents, - views::View* anchor_view, - const gfx::Point& anchor_point, - DisplayReason reason); + PasswordAutoSignInView(content::WebContents* web_contents, + views::View* anchor_view, + DisplayReason reason); #if defined(UNIT_TEST) static void set_auto_signin_toast_timeout(int seconds) {
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc index 463b433..da8ef01 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc +++ b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
@@ -44,7 +44,7 @@ } PasswordBubbleViewBase* bubble = - CreateBubble(web_contents, anchor_view, gfx::Point(), reason); + CreateBubble(web_contents, anchor_view, reason); DCHECK(bubble); DCHECK(bubble == g_manage_passwords_bubble_); @@ -82,25 +82,20 @@ PasswordBubbleViewBase* PasswordBubbleViewBase::CreateBubble( content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason) { PasswordBubbleViewBase* view = nullptr; password_manager::ui::State model_state = PasswordsModelDelegateFromWebContents(web_contents)->GetState(); if (model_state == password_manager::ui::MANAGE_STATE) { - view = - new PasswordItemsView(web_contents, anchor_view, anchor_point, reason); + view = new PasswordItemsView(web_contents, anchor_view, reason); } else if (model_state == password_manager::ui::AUTO_SIGNIN_STATE) { - view = new PasswordAutoSignInView(web_contents, anchor_view, anchor_point, - reason); + view = new PasswordAutoSignInView(web_contents, anchor_view, reason); } else if (model_state == password_manager::ui::CONFIRMATION_STATE) { - view = new PasswordSaveConfirmationView(web_contents, anchor_view, - anchor_point, reason); + view = new PasswordSaveConfirmationView(web_contents, anchor_view, reason); } else if (model_state == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE || model_state == password_manager::ui::PENDING_PASSWORD_STATE) { - view = new PasswordPendingView(web_contents, anchor_view, anchor_point, - reason); + view = new PasswordPendingView(web_contents, anchor_view, reason); } else { NOTREACHED(); } @@ -137,9 +132,8 @@ PasswordBubbleViewBase::PasswordBubbleViewBase( content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason) - : LocationBarBubbleDelegateView(anchor_view, anchor_point, web_contents), + : LocationBarBubbleDelegateView(anchor_view, gfx::Point(), web_contents), model_(PasswordsModelDelegateFromWebContents(web_contents), reason == AUTOMATIC ? ManagePasswordsBubbleModel::AUTOMATIC : ManagePasswordsBubbleModel::USER_ACTION),
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_base.h b/chrome/browser/ui/views/passwords/password_bubble_view_base.h index ab9e2ef..a0b5cc76 100644 --- a/chrome/browser/ui/views/passwords/password_bubble_view_base.h +++ b/chrome/browser/ui/views/passwords/password_bubble_view_base.h
@@ -39,7 +39,6 @@ static PasswordBubbleViewBase* CreateBubble( content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason); // Closes the existing bubble. @@ -61,7 +60,6 @@ protected: PasswordBubbleViewBase(content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason); ~PasswordBubbleViewBase() override;
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc index 215f27d..92c6c914 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.cc +++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -233,9 +233,8 @@ PasswordItemsView::PasswordItemsView(content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason) - : PasswordBubbleViewBase(web_contents, anchor_view, anchor_point, reason) { + : PasswordBubbleViewBase(web_contents, anchor_view, reason) { DCHECK_EQ(password_manager::ui::MANAGE_STATE, model()->state()); if (model()->local_credentials().empty()) {
diff --git a/chrome/browser/ui/views/passwords/password_items_view.h b/chrome/browser/ui/views/passwords/password_items_view.h index d992a7f..42a92d1 100644 --- a/chrome/browser/ui/views/passwords/password_items_view.h +++ b/chrome/browser/ui/views/passwords/password_items_view.h
@@ -38,7 +38,6 @@ public: PasswordItemsView(content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason); ~PasswordItemsView() override;
diff --git a/chrome/browser/ui/views/passwords/password_pending_view.cc b/chrome/browser/ui/views/passwords/password_pending_view.cc index 3b21bee..cdb0d29 100644 --- a/chrome/browser/ui/views/passwords/password_pending_view.cc +++ b/chrome/browser/ui/views/passwords/password_pending_view.cc
@@ -201,9 +201,8 @@ PasswordPendingView::PasswordPendingView(content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason) - : PasswordBubbleViewBase(web_contents, anchor_view, anchor_point, reason), + : PasswordBubbleViewBase(web_contents, anchor_view, reason), is_update_bubble_(model()->state() == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE), sign_in_promo_(nullptr),
diff --git a/chrome/browser/ui/views/passwords/password_pending_view.h b/chrome/browser/ui/views/passwords/password_pending_view.h index a2adc5d..3f649a2 100644 --- a/chrome/browser/ui/views/passwords/password_pending_view.h +++ b/chrome/browser/ui/views/passwords/password_pending_view.h
@@ -26,7 +26,6 @@ public: PasswordPendingView(content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason); views::View* GetUsernameTextfieldForTest() const;
diff --git a/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc b/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc index e319957d..52ce2fed 100644 --- a/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc +++ b/chrome/browser/ui/views/passwords/password_save_confirmation_view.cc
@@ -16,9 +16,8 @@ PasswordSaveConfirmationView::PasswordSaveConfirmationView( content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason) - : PasswordBubbleViewBase(web_contents, anchor_view, anchor_point, reason) { + : PasswordBubbleViewBase(web_contents, anchor_view, reason) { SetLayoutManager(std::make_unique<views::FillLayout>()); auto label = std::make_unique<views::StyledLabel>(
diff --git a/chrome/browser/ui/views/passwords/password_save_confirmation_view.h b/chrome/browser/ui/views/passwords/password_save_confirmation_view.h index 3ccbf97..0178a02d 100644 --- a/chrome/browser/ui/views/passwords/password_save_confirmation_view.h +++ b/chrome/browser/ui/views/passwords/password_save_confirmation_view.h
@@ -16,7 +16,6 @@ public: explicit PasswordSaveConfirmationView(content::WebContents* web_contents, views::View* anchor_view, - const gfx::Point& anchor_point, DisplayReason reason); ~PasswordSaveConfirmationView() override;
diff --git a/chrome/browser/ui/views/sharing/click_to_call/click_to_call_icon_view.cc b/chrome/browser/ui/views/sharing/click_to_call/click_to_call_icon_view.cc index a769308..a765e16 100644 --- a/chrome/browser/ui/views/sharing/click_to_call/click_to_call_icon_view.cc +++ b/chrome/browser/ui/views/sharing/click_to_call/click_to_call_icon_view.cc
@@ -34,9 +34,8 @@ views::BubbleDialogDelegateView* ClickToCallIconView::GetBubble() const { auto* controller = GetControllerFromWebContents(GetWebContents()); - return controller - ? static_cast<ClickToCallDialogView*>(controller->GetDialog()) - : nullptr; + return controller ? static_cast<ClickToCallDialogView*>(controller->dialog()) + : nullptr; } bool ClickToCallIconView::Update() {
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index 63f6670..ef202ef9 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -285,6 +285,8 @@ static constexpr float kOverflowMenuItemXPadding = 0.024f; static constexpr float kOverflowMenuMaxSpan = 0.384f - kOverflowMenuYPadding; +static constexpr const char* kCrashVrBrowserUrl = "chrome://crash-vr-browser"; + } // namespace vr #endif // CHROME_BROWSER_VR_UI_SCENE_CONSTANTS_H_
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index b6992b9..45afa74 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1103,6 +1103,16 @@ return kToastTimeoutSeconds; } +NOINLINE void CrashIntentionally() { + LOG(ERROR) << "Crashing VR browser"; + + static int static_variable_to_make_this_function_unique = 0; + base::debug::Alias(&static_variable_to_make_this_function_unique); + + volatile int* zero = nullptr; + *zero = 0; +} + } // namespace UiSceneCreator::UiSceneCreator(UiBrowserInterface* browser, @@ -2633,6 +2643,8 @@ omnibox_text_field->set_input_committed_callback(base::BindRepeating( [](Model* model, UiBrowserInterface* browser, Ui* ui, const EditedText& text) { + if (text.current.text == base::UTF8ToUTF16(kCrashVrBrowserUrl)) + CrashIntentionally(); if (!model->omnibox_suggestions.empty()) { browser->Navigate(model->omnibox_suggestions.front().destination, NavigationMethod::kOmniboxUrlEntry);
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 67f4d93b..348f63b 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -715,11 +715,6 @@ // installed through policy. const char kDisableLoginScreenApps[] = "disable-login-screen-apps"; -// Provides the name of the mojo service running in a mash utility process. -// NOTE: Used by the Chrome OS crash_reporter to identify mash processes. If you -// change or remove the flag please update platform2/crash_reporter. -const char kMashServiceName[] = "mash-service-name"; - // Use a short (1 second) timeout for merge session loader throttle testing. const char kShortMergeSessionTimeoutForTest[] = "short-merge-session-timeout-for-test";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index d1333f4..8958f38 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -211,7 +211,6 @@ extern const char kCroshCommand[]; extern const char kDisableLoggingRedirect[]; extern const char kDisableLoginScreenApps[]; -extern const char kMashServiceName[]; extern const char kShortMergeSessionTimeoutForTest[]; extern const char kSchedulerConfiguration[]; extern const char kSchedulerConfigurationConservative[];
diff --git a/chrome/test/android/test_trusted_web_activity/BUILD.gn b/chrome/test/android/test_trusted_web_activity/BUILD.gn index 36dac01b..1201e70 100644 --- a/chrome/test/android/test_trusted_web_activity/BUILD.gn +++ b/chrome/test/android/test_trusted_web_activity/BUILD.gn
@@ -14,6 +14,6 @@ "src/org/chromium/chrome/browser/browserservices/TestTrustedWebActivityService.java", ] deps = [ - "//third_party/android_sdk/androidx_browser:androidx_browser_java" + "//third_party/custom_tabs_client:custom_tabs_support_java", ] }
diff --git a/chrome/test/android/test_trusted_web_activity/src/org/chromium/chrome/browser/browserservices/TestTrustedWebActivityService.java b/chrome/test/android/test_trusted_web_activity/src/org/chromium/chrome/browser/browserservices/TestTrustedWebActivityService.java index f660b53..5735160d 100644 --- a/chrome/test/android/test_trusted_web_activity/src/org/chromium/chrome/browser/browserservices/TestTrustedWebActivityService.java +++ b/chrome/test/android/test_trusted_web_activity/src/org/chromium/chrome/browser/browserservices/TestTrustedWebActivityService.java
@@ -5,8 +5,7 @@ package org.chromium.chrome.browser.browserservices; import android.app.Notification; - -import androidx.browser.trusted.TrustedWebActivityService; +import android.support.customtabs.trusted.TrustedWebActivityService; /** * A TrustedWebActivityService to be used in TrustedWebActivityClientTest.
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 0cc3ae1c..9024439 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -15,9 +15,6 @@ 'SlowLoadingPageTest.testRefreshShouldBlockUntilPageLoads', 'PageLoadingTest.testShouldTimeoutIfAPageTakesTooLongToRefresh', - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2854 - 'ChromeOptionsFunctionalTest.canSetAcceptInsecureCerts', - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2858 'ElementFindingTest.testFindingMultipleElementsByInvalidClassNameShouldThrow', 'ElementFindingTest.testFindingMultipleElementsByCompoundClassNameShouldThrow', @@ -34,15 +31,30 @@ 'CombinedInputActionsTest.testChordControlCutAndPaste', #https://bugs.chromium.org/p/chromedriver/issues/detail?id=2971 + 'ChromeDevToolsProfilerTest.aSimpleStartStopAndGetProfilerTest', + 'ChromeDevToolsSecurityTest.loadInsecureWebsite', 'ChromeDevToolsProfilerTest.sampleProfileEvents', + 'ChromeDevToolsProfilerTest.sampleSetStartPreciseCoverageTest', ] _READY_TO_RUN_FILTER = [ # marked as not yet implemented with chrome but already works - 'ProxySettingTest.canUsePACThatOnlyProxiesCertainHosts', + 'AlertsTest.testIncludesAlertTextInUnhandledAlertException', + 'BasicKeyboardInterfaceTest.testSelectionSelectBySymbol', + 'BasicKeyboardInterfaceTest.testSelectionSelectByWord', + 'BasicMouseInterfaceTest.testCanMoveOverAndOutOfAnElement', + 'BasicMouseInterfaceTest.testMoveMouseByOffsetOverAndOutOfAnElement', + 'BasicMouseInterfaceTest.testMovingMouseToRelativeElementOffset', + 'BasicMouseInterfaceTest.testMovingMouseToRelativeZeroElementOffset', + 'CombinedInputActionsTest.testClickAfterMoveToAnElementWithAnOffsetShouldUseLastMousePosition', + 'ContentEditableTest.appendsTextToEndOfContentEditableWithMultipleTextNodes', 'ContentEditableTest.testShouldAppendToTinyMCE', 'ContentEditableTest.testShouldBeAbleToTypeIntoContentEditableElementWithExistingValue', - 'ContentEditableTest.appendsTextToEndOfContentEditableWithMultipleTextNodes', + 'CookieImplementationTest.canHandleHttpOnlyCookie', + 'ExecutingJavascriptTest.testShouldBeAbleToReturnADateObject', + 'PageLoadingTest.testEagerStrategyShouldNotWaitForResources', + 'PageLoadingTest.testEagerStrategyShouldNotWaitForResourcesOnRefresh', + 'PageLoadingTest.testEagerStrategyShouldWaitForDocumentToBeLoaded', 'WindowSwitchingTest.canOpenANewWindow', ]
diff --git a/chrome/test/data/pdf/accessibility/hello-world-expected-auralinux.txt b/chrome/test/data/pdf/accessibility/hello-world-expected-auralinux.txt index ee8c26c..31e73ffa 100644 --- a/chrome/test/data/pdf/accessibility/hello-world-expected-auralinux.txt +++ b/chrome/test/data/pdf/accessibility/hello-world-expected-auralinux.txt
@@ -1,5 +1,5 @@ [embedded component] -++[panel] +++[document frame] ++++[landmark] name='Page 1' ++++++[paragraph] ++++++++[text] name='Hello, world!'
diff --git a/chrome/test/data/pdf/accessibility/hello-world-expected-blink.txt b/chrome/test/data/pdf/accessibility/hello-world-expected-blink.txt index 6fad2681..850b44f4 100644 --- a/chrome/test/data/pdf/accessibility/hello-world-expected-blink.txt +++ b/chrome/test/data/pdf/accessibility/hello-world-expected-blink.txt
@@ -1,6 +1,6 @@ embeddedObject -++group restriction=readOnly -++++region name='Page 1' restriction=readOnly +++document restriction=readOnly +++++region name='Page 1' restriction=readOnly isPageBreakingObject=true ++++++paragraph restriction=readOnly ++++++++staticText name='Hello, world!' restriction=readOnly ++++++++++inlineTextBox name='Hello, world!' restriction=readOnly
diff --git a/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt index ebda394..be9ef8c 100644 --- a/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt +++ b/chrome/test/data/pdf/accessibility/hello-world-expected-uia-win.txt
@@ -1,4 +1,5 @@ group -++group +++document ++++region Name='Page 1' ++++++group +++++++++description Name='Hello, world!'
diff --git a/chrome/test/data/pdf/accessibility/hello-world-expected-win.txt b/chrome/test/data/pdf/accessibility/hello-world-expected-win.txt index c33fc42..4bfc3dab 100644 --- a/chrome/test/data/pdf/accessibility/hello-world-expected-win.txt +++ b/chrome/test/data/pdf/accessibility/hello-world-expected-win.txt
@@ -1,5 +1,5 @@ ROLE_SYSTEM_GROUPING FOCUSABLE -++ROLE_SYSTEM_GROUPING READONLY +++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++++IA2_ROLE_LANDMARK name='Page 1' READONLY ++++++IA2_ROLE_PARAGRAPH READONLY ++++++++ROLE_SYSTEM_STATICTEXT name='Hello, world!' READONLY
diff --git a/chrome/test/data/pdf/accessibility/multi-page-expected-auralinux.txt b/chrome/test/data/pdf/accessibility/multi-page-expected-auralinux.txt new file mode 100644 index 0000000..f8013d8 --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page-expected-auralinux.txt
@@ -0,0 +1,8 @@ +[embedded component] +++[document frame] +++++[landmark] name='Page 1' +++++++[paragraph] +++++++++[text] name='Page 1' +++++[landmark] name='Page 2' +++++++[paragraph] +++++++++[text] name='Page 2'
diff --git a/chrome/test/data/pdf/accessibility/multi-page-expected-blink.txt b/chrome/test/data/pdf/accessibility/multi-page-expected-blink.txt new file mode 100644 index 0000000..58d374e --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page-expected-blink.txt
@@ -0,0 +1,10 @@ +embeddedObject +++document restriction=readOnly +++++region name='Page 1' restriction=readOnly isPageBreakingObject=true +++++++paragraph restriction=readOnly +++++++++staticText name='Page 1' restriction=readOnly +++++++++++inlineTextBox name='Page 1' restriction=readOnly +++++region name='Page 2' restriction=readOnly isPageBreakingObject=true +++++++paragraph restriction=readOnly +++++++++staticText name='Page 2' restriction=readOnly +++++++++++inlineTextBox name='Page 2' restriction=readOnly
diff --git a/chrome/test/data/pdf/accessibility/multi-page-expected-mac.txt b/chrome/test/data/pdf/accessibility/multi-page-expected-mac.txt new file mode 100644 index 0000000..d7dd6639 --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page-expected-mac.txt
@@ -0,0 +1,8 @@ +AXGroup AXDescription='Page 1 Page 2' +++AXGroup +++++AXGroup AXDescription='Page 1' +++++++AXGroup +++++++++AXStaticText AXValue='Page 1' +++++AXGroup AXDescription='Page 2' +++++++AXGroup +++++++++AXStaticText AXValue='Page 2'
diff --git a/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt new file mode 100644 index 0000000..4886f10f --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page-expected-uia-win.txt
@@ -0,0 +1,8 @@ +group +++document +++++region Name='Page 1' +++++++group +++++++++description Name='Page 1' +++++region Name='Page 2' +++++++group +++++++++description Name='Page 2'
diff --git a/chrome/test/data/pdf/accessibility/multi-page-expected-win.txt b/chrome/test/data/pdf/accessibility/multi-page-expected-win.txt new file mode 100644 index 0000000..f0eaa0e --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page-expected-win.txt
@@ -0,0 +1,8 @@ +ROLE_SYSTEM_GROUPING FOCUSABLE +++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++++IA2_ROLE_LANDMARK name='Page 1' READONLY +++++++IA2_ROLE_PARAGRAPH READONLY +++++++++ROLE_SYSTEM_STATICTEXT name='Page 1' READONLY +++++IA2_ROLE_LANDMARK name='Page 2' READONLY +++++++IA2_ROLE_PARAGRAPH READONLY +++++++++ROLE_SYSTEM_STATICTEXT name='Page 2' READONLY
diff --git a/chrome/test/data/pdf/accessibility/multi-page.in b/chrome/test/data/pdf/accessibility/multi-page.in new file mode 100644 index 0000000..406f338 --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page.in
@@ -0,0 +1,66 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R +>> +endobj +{{object 2 0}} << + /Type /Pages + /MediaBox [ 0 0 200 250 ] + /Count 2 + /Kids [ 3 0 R 6 0 R ] +>> +endobj +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /Resources << + /Font << + /F1 4 0 R + >> + >> + /Contents 5 0 R +>> +endobj +{{object 4 0}} << + /Type /Font + /Subtype /Type1 + /BaseFont /Helvetica +>> +endobj +{{object 5 0}} << + {{streamlen}} +>> +stream +BT +20 100 Td +/F1 16 Tf +(Page 1) Tj +ET +endstream +endobj +{{object 6 0}} << + /Type /Page + /Parent 2 0 R + /Resources << + /Font << + /F1 4 0 R + >> + >> + /Contents 7 0 R +>> +{{object 7 0}} << + {{streamlen}} +>> +stream +BT +20 100 Td +/F1 16 Tf +(Page 2) Tj +ET +endstream +endobj +{{xref}} +{{trailer}} +{{startxref}} +%%EOF
diff --git a/chrome/test/data/pdf/accessibility/multi-page.pdf b/chrome/test/data/pdf/accessibility/multi-page.pdf new file mode 100644 index 0000000..621b71c7 --- /dev/null +++ b/chrome/test/data/pdf/accessibility/multi-page.pdf
@@ -0,0 +1,80 @@ +%PDF-1.7 +% ò¤ô +1 0 obj << + /Type /Catalog + /Pages 2 0 R +>> +endobj +2 0 obj << + /Type /Pages + /MediaBox [ 0 0 200 250 ] + /Count 2 + /Kids [ 3 0 R 6 0 R ] +>> +endobj +3 0 obj << + /Type /Page + /Parent 2 0 R + /Resources << + /Font << + /F1 4 0 R + >> + >> + /Contents 5 0 R +>> +endobj +4 0 obj << + /Type /Font + /Subtype /Type1 + /BaseFont /Helvetica +>> +endobj +5 0 obj << + /Length 38 +>> +stream +BT +20 100 Td +/F1 16 Tf +(Page 1) Tj +ET +endstream +endobj +6 0 obj << + /Type /Page + /Parent 2 0 R + /Resources << + /Font << + /F1 4 0 R + >> + >> + /Contents 7 0 R +>> +7 0 obj << + /Length 38 +>> +stream +BT +20 100 Td +/F1 16 Tf +(Page 2) Tj +ET +endstream +endobj +xref +0 8 +0000000000 65535 f +0000000015 00000 n +0000000068 00000 n +0000000167 00000 n +0000000293 00000 n +0000000369 00000 n +0000000458 00000 n +0000000577 00000 n +trailer << + /Root 1 0 R + /Size 8 +>> +startxref +666 +%%EOF
diff --git a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-auralinux.txt b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-auralinux.txt index b1ff437..2822240a 100644 --- a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-auralinux.txt +++ b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-auralinux.txt
@@ -1,5 +1,5 @@ [embedded component] -++[panel] +++[document frame] ++++[landmark] name='Page 1' ++++++[heading] ++++++++[text] name='Heading<newline>'
diff --git a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-blink.txt b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-blink.txt index 30b0e8ca..9b85331 100644 --- a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-blink.txt +++ b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-blink.txt
@@ -1,6 +1,6 @@ embeddedObject -++group restriction=readOnly -++++region name='Page 1' restriction=readOnly +++document restriction=readOnly +++++region name='Page 1' restriction=readOnly isPageBreakingObject=true ++++++heading hierarchicalLevel=2 restriction=readOnly ++++++++staticText name='Heading<newline>' restriction=readOnly ++++++++++inlineTextBox name='Heading<newline>' restriction=readOnly
diff --git a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt index 6aa78b76..817f686b 100644 --- a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt +++ b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-uia-win.txt
@@ -1,8 +1,12 @@ group -++group +++document ++++region Name='Page 1' ++++++heading ++++++group +++++++++description Name='This is a small pdf file:<newline>' ++++++group +++++++++description Name='Lorem Ipsum is simply dummy text of the printing and typesetting industry.<newline>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.<newline>' ++++++group +++++++++description Name='It has survived not only five centuries, but also the leap into electronic typesetting,<newline>remaining essentially unchanged. It was popularised in the 1960s with the release of<newline>Letraset sheets containing Lorem Ipsum passages, and more recently with desktop<newline>publishing software like Aldus PageMaker including versions of Lorem Ipsum.<newline>' ++++++group +++++++++description Name='Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots<newline>in a piece of classical Latin literature from 45 BC, making it over 2000 years old.'
diff --git a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-win.txt b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-win.txt index 9a753255..18bfc0fd 100644 --- a/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-win.txt +++ b/chrome/test/data/pdf/accessibility/paragraphs-and-heading-untagged-expected-win.txt
@@ -1,5 +1,5 @@ ROLE_SYSTEM_GROUPING FOCUSABLE -++ROLE_SYSTEM_GROUPING READONLY +++ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE ++++IA2_ROLE_LANDMARK name='Page 1' READONLY ++++++IA2_ROLE_HEADING READONLY ++++++++ROLE_SYSTEM_STATICTEXT name='Heading<newline>' READONLY
diff --git a/chrome/test/data/webui/bookmarks/bookmarks_browsertest.js b/chrome/test/data/webui/bookmarks/bookmarks_browsertest.js index ca000ed..7d3ac90 100644 --- a/chrome/test/data/webui/bookmarks/bookmarks_browsertest.js +++ b/chrome/test/data/webui/bookmarks/bookmarks_browsertest.js
@@ -66,7 +66,7 @@ __proto__: BookmarksBrowserTest.prototype, extraLibraries: BookmarksBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'command_manager_test.js', ]), };
diff --git a/chrome/test/data/webui/bookmarks/bookmarks_focus_test.js b/chrome/test/data/webui/bookmarks/bookmarks_focus_test.js index f6c24ae..e8bd761 100644 --- a/chrome/test/data/webui/bookmarks/bookmarks_focus_test.js +++ b/chrome/test/data/webui/bookmarks/bookmarks_focus_test.js
@@ -19,7 +19,7 @@ extraLibraries: [ ...PolymerInteractiveUITest.prototype.extraLibraries, '//ui/webui/resources/js/util.js', - '../settings/test_util.js', + '../test_util.js', '../test_store.js', 'test_command_manager.js', 'test_store.js',
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js index 7625733..8b52458 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -150,7 +150,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_drawer_tests.js', ]), }; @@ -173,7 +173,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_scrollable_behavior_tests.js', ]), }; @@ -393,7 +393,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_dialog_test.js', ]), }; @@ -416,7 +416,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_slider_test.js', ]), }; @@ -463,7 +463,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_toast_manager_test.js', ]), }; @@ -487,7 +487,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_radio_button_test.js', ]), }; @@ -511,7 +511,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_radio_group_test.js', ]), }; @@ -534,7 +534,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_button_tests.js', ]), }; @@ -558,7 +558,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_icon_button_tests.js', ]), }; @@ -628,7 +628,7 @@ /** @override */ extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_searchable_drop_down_tests.js', ]), };
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js index 5040264..4800367 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_focus_test.js
@@ -23,7 +23,7 @@ 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html', extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_action_menu_test.js', ]), }; @@ -65,7 +65,7 @@ /** @override */ extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_toggle_test.js', ]), }; @@ -89,7 +89,7 @@ /** @override */ extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_checkbox_test.js', ]), }; @@ -112,7 +112,7 @@ /** @override */ extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'cr_input_test.js', ]), }; @@ -161,7 +161,7 @@ /** @override */ extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ '//ui/webui/resources/js/util.js', - '../settings/test_util.js', + '../test_util.js', 'cr_expand_button_focus_tests.js', ]), }; @@ -185,7 +185,7 @@ /** @override */ extraLibraries: CrElementsFocusTest.prototype.extraLibraries.concat([ '//ui/webui/resources/js/util.js', - '../settings/test_util.js', + '../test_util.js', 'cr_tabs_test.js', ]), };
diff --git a/chrome/test/data/webui/cr_focus_row_behavior_interactive_test.js b/chrome/test/data/webui/cr_focus_row_behavior_interactive_test.js index a31e1980..fea56b29 100644 --- a/chrome/test/data/webui/cr_focus_row_behavior_interactive_test.js +++ b/chrome/test/data/webui/cr_focus_row_behavior_interactive_test.js
@@ -23,7 +23,7 @@ ...PolymerTest.prototype.extraLibraries, '//ui/webui/resources/js/util.js', 'cr_focus_row_behavior_test.js', - 'settings/test_util.js', + 'test_util.js', ], /** @override */
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js index b1e1407cb..7d38e22 100644 --- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js +++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -29,7 +29,7 @@ '../../../../../ui/webui/resources/js/promise_resolver.js', '../../../../../ui/webui/resources/js/webui_resource_test.js', '../fake_chrome_event.js', - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'test_service.js', ]; @@ -540,7 +540,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'manager_test.js', ]); } @@ -594,7 +594,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'manager_test.js', ]); } @@ -707,7 +707,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'pack_dialog_test.js', ]); } @@ -761,7 +761,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'options_dialog_test.js', ]); } @@ -892,7 +892,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'error_console_test.js', ]); }
diff --git a/chrome/test/data/webui/extensions/cr_extensions_interactive_ui_tests.js b/chrome/test/data/webui/extensions/cr_extensions_interactive_ui_tests.js index d659f1a..6f0fc156 100644 --- a/chrome/test/data/webui/extensions/cr_extensions_interactive_ui_tests.js +++ b/chrome/test/data/webui/extensions/cr_extensions_interactive_ui_tests.js
@@ -24,7 +24,7 @@ get extraLibraries() { return [ ...super.extraLibraries, - '../settings/test_util.js', + '../test_util.js', ]; }
diff --git a/chrome/test/data/webui/find_shortcut_behavior_browsertest.js b/chrome/test/data/webui/find_shortcut_behavior_browsertest.js index 24575db..67c6b705 100644 --- a/chrome/test/data/webui/find_shortcut_behavior_browsertest.js +++ b/chrome/test/data/webui/find_shortcut_behavior_browsertest.js
@@ -26,8 +26,7 @@ extraLibraries: [ ...PolymerTest.prototype.extraLibraries, '//ui/webui/resources/js/util.js', - 'settings/test_util.js', - 'settings/test_util.js', + 'test_util.js', 'find_shortcut_behavior_test.js', ], };
diff --git a/chrome/test/data/webui/history/history_browsertest.js b/chrome/test/data/webui/history/history_browsertest.js index 7b378ef..2f325b97 100644 --- a/chrome/test/data/webui/history/history_browsertest.js +++ b/chrome/test/data/webui/history/history_browsertest.js
@@ -188,7 +188,7 @@ __proto__: HistoryBrowserTest.prototype, extraLibraries: HistoryBrowserTest.prototype.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'history_synced_tabs_test.js', ]), };
diff --git a/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js b/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js index e272a7a..cc978e9 100644 --- a/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js +++ b/chrome/test/data/webui/multidevice_setup/multidevice_setup_browsertest.js
@@ -24,7 +24,7 @@ '../test_browser_proxy.js', '../fake_chrome_event.js', // Necessary for fake_quick_unlock_private.js '../settings/chromeos/fake_quick_unlock_private.js', - '../settings/test_util.js', + '../test_util.js', 'integration_test.js', 'setup_succeeded_page_test.js', 'start_setup_page_test.js',
diff --git a/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js b/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js index 837e2018..e08136c 100644 --- a/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js +++ b/chrome/test/data/webui/print_preview/print_preview_interactive_ui_tests.js
@@ -56,7 +56,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '//chrome/test/data/webui/settings/test_util.js', + '//chrome/test/data/webui/test_util.js', 'print_header_interactive_test.js', ]); } @@ -84,7 +84,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '//chrome/test/data/webui/settings/test_util.js', + '//chrome/test/data/webui/test_util.js', 'button_strip_interactive_test.js', ]); } @@ -119,7 +119,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '//chrome/test/data/webui/settings/test_util.js', + '//chrome/test/data/webui/test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js', @@ -167,7 +167,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'pages_settings_test.js', ]); @@ -207,7 +207,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'number_settings_section_interactive_test.js', ]); @@ -238,7 +238,7 @@ get extraLibraries() { return super.extraLibraries.concat([ '//ui/webui/resources/js/util.js', - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'scaling_settings_interactive_test.js', ]);
diff --git a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js index cca997c..0b8ce81 100644 --- a/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/print_preview_ui_browsertest.js
@@ -54,7 +54,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js', @@ -88,7 +88,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js', @@ -119,7 +119,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'pages_settings_test.js', ]); @@ -157,7 +157,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'native_layer_stub.js', 'plugin_stub.js', @@ -198,7 +198,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'settings_select_test.js', ]); @@ -219,7 +219,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'select_behavior_test.js', ]); } @@ -250,7 +250,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'number_settings_section_test.js', ]); } @@ -313,7 +313,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'model_test.js', ]); @@ -355,7 +355,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'model_settings_availability_test.js', ]); @@ -377,7 +377,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'model_settings_policy_test.js', ]); @@ -496,7 +496,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'link_container_test.js', ]); @@ -538,7 +538,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'native_layer_stub.js', 'plugin_stub.js', @@ -579,7 +579,7 @@ get extraLibraries() { return super.extraLibraries.concat([ '//ui/webui/resources/js/cr/event_target.js', - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js', @@ -633,7 +633,7 @@ get extraLibraries() { return super.extraLibraries.concat([ '//ui/webui/resources/js/web_ui_listener_behavior.js', - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js', @@ -733,7 +733,7 @@ return super.extraLibraries.concat([ '//ui/webui/resources/js/web_ui_listener_behavior.js', '//ui/webui/resources/js/cr/event_target.js', - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js', @@ -774,7 +774,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'advanced_dialog_test.js', ]); @@ -825,7 +825,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'native_layer_stub.js', 'plugin_stub.js', @@ -858,7 +858,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'custom_margins_test.js', ]); @@ -942,7 +942,7 @@ get extraLibraries() { return super.extraLibraries.concat([ '//ui/webui/resources/js/web_ui_listener_behavior.js', - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'native_layer_stub.js', 'print_preview_test_utils.js', @@ -997,7 +997,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'header_test.js', ]); } @@ -1042,7 +1042,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'header_new_test.js', ]); } @@ -1083,7 +1083,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'button_strip_test.js', ]); } @@ -1157,7 +1157,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'advanced_item_test.js', ]); @@ -1203,7 +1203,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'destination_list_test.js', ]); } @@ -1266,7 +1266,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'native_layer_stub.js', 'plugin_stub.js', @@ -1331,7 +1331,7 @@ return super.extraLibraries.concat([ '//ui/webui/resources/js/web_ui_listener_behavior.js', '../test_browser_proxy.js', - '../settings/test_util.js', + '../test_util.js', 'cloud_print_interface_stub.js', 'print_preview_test_utils.js', 'native_layer_stub.js', @@ -1420,7 +1420,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'scaling_settings_test.js', ]); @@ -1460,7 +1460,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'copies_settings_test.js', ]); @@ -1481,7 +1481,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'media_size_settings_test.js', ]); @@ -1502,7 +1502,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'dpi_settings_test.js', ]); @@ -1523,7 +1523,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'other_options_settings_test.js', ]); @@ -1544,7 +1544,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'layout_settings_test.js', ]); @@ -1565,7 +1565,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'color_settings_test.js', ]); @@ -1586,7 +1586,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'margins_settings_test.js', ]); @@ -1607,7 +1607,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'pages_per_sheet_settings_test.js', ]); @@ -1628,7 +1628,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'duplex_settings_test.js', ]); @@ -1650,7 +1650,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'print_preview_test_utils.js', 'pin_settings_test.js', ]); @@ -1672,7 +1672,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'cloud_print_interface_stub.js', 'native_layer_stub.js',
diff --git a/chrome/test/data/webui/set_time_dialog_browsertest.js b/chrome/test/data/webui/set_time_dialog_browsertest.js index 0ae1342..df58137e 100644 --- a/chrome/test/data/webui/set_time_dialog_browsertest.js +++ b/chrome/test/data/webui/set_time_dialog_browsertest.js
@@ -187,6 +187,46 @@ assertGT(timeInSeconds, todaySeconds); }); }); + + suite('NullTimezone', () => { + suiteSetup(() => { + loadTimeData.overrideValues({ + currentTimezoneId: '', + timezoneList: [], + }); + }); + + test('SetDateNullTimezone', () => { + const dateInput = setTimeElement.$$('#dateInput'); + assertTrue(!!dateInput); + + assertEquals(null, setTimeElement.$$('#timezoneSelect')); + + // Simulates the user changing the date picker backward by two days. We + // are changing the date to make the test simpler. Changing the time + // would require timezone manipulation and handling corner cases over + // midnight. valuesAsDate return the time in UTC, therefore the amount + // of days here must be bigger than one to avoid situations where the + // new time and old time are in the same day. + const today = dateInput.valueAsDate; + const twoDaysAgo = new Date(today.getTime() - 2 * 24 * 60 * 60 * 1000); + dateInput.focus(); + dateInput.valueAsDate = twoDaysAgo; + setTimeElement.$$('#doneButton').click(); + + // Verify the page sends a request to move time backward. + return testBrowserProxy.whenCalled('setTimeInSeconds') + .then(newTimeSeconds => { + const todaySeconds = today.getTime() / 1000; + // Check that the current time is bigger than the new time, which + // is supposed to be two days ago. The exact value isn't + // important, checking it is difficult because it depends on the + // current time, which is constantly updated, therefore we only + // assert that one is bigger than the other. + assertGT(todaySeconds, newTimeSeconds); + }); + }); + }); }); mocha.run();
diff --git a/chrome/test/data/webui/settings/a11y/sign_out_a11y_test.js b/chrome/test/data/webui/settings/a11y/sign_out_a11y_test.js index ce00ee06..023acd0 100644 --- a/chrome/test/data/webui/settings/a11y/sign_out_a11y_test.js +++ b/chrome/test/data/webui/settings/a11y/sign_out_a11y_test.js
@@ -26,8 +26,8 @@ // Include files that define the mocha tests. extraLibraries: SettingsAccessibilityTest.prototype.extraLibraries.concat([ '../../test_browser_proxy.js', + '../../test_util.js', '../sync_test_util.js', - '../test_util.js', '../test_sync_browser_proxy.js', ]), };
diff --git a/chrome/test/data/webui/settings/about_page_tests.js b/chrome/test/data/webui/settings/about_page_tests.js index 586b3ef..a2831f2 100644 --- a/chrome/test/data/webui/settings/about_page_tests.js +++ b/chrome/test/data/webui/settings/about_page_tests.js
@@ -483,13 +483,6 @@ assertTrue(!!page.$.regulatoryInfo.hidden); assertTrue(!!page.$.crostiniLicense.hidden); }); - - test('detailed build info page', () => { - page.scroller = page.offsetParent; - assertTrue(!!page.$['detailed-build-info-trigger']); - page.$['detailed-build-info-trigger'].click(); - assertTrue(!!page.$$('settings-detailed-build-info')); - }); } if (!cr.isChromeOS) {
diff --git a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js index 72671a8..34fa77c 100644 --- a/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_about_page_tests.js
@@ -439,6 +439,13 @@ await checkHasEndOfLife(false); }); + test('detailed build info page', () => { + page.scroller = page.offsetParent; + assertTrue(!!page.$['detailed-build-info-trigger']); + page.$['detailed-build-info-trigger'].click(); + assertTrue(!!page.$$('settings-detailed-build-info')); + }); + test('GetHelp', function() { assertTrue(!!page.$.help); page.$.help.click(); @@ -464,7 +471,7 @@ } return { - // TODO(aee): move the detailed build info and channel switch dialog tests + // TODO(crbug.com/950007): Move the channel switch dialog tests to here // from the browser about page tests when those CrOS-specific parts are // removed from the browser about page. registerTests: registerAboutPageTests,
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index e744ed2..20f2760 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -57,7 +57,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', BROWSER_SETTINGS_PATH + 'test_lifetime_browser_proxy.js', BROWSER_SETTINGS_PATH + 'test_about_page_browser_proxy.js', @@ -104,7 +104,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', 'os_advanced_page_browsertest.js', ]); } @@ -397,7 +397,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', 'os_settings_main_test.js', ]); @@ -414,7 +414,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', 'os_settings_menu_test.js', ]); } @@ -503,7 +503,7 @@ get extraLibraries() { return super.extraLibraries.concat([ BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', 'test_multidevice_browser_proxy.js', 'multidevice_smartlock_subpage_test.js', ]); @@ -611,7 +611,7 @@ return super.extraLibraries.concat([ BROWSER_SETTINGS_PATH + '../fake_chrome_event.js', BROWSER_SETTINGS_PATH + 'fake_settings_private.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', 'fake_quick_unlock_private.js', 'fake_quick_unlock_uma.js', 'quick_unlock_authenticate_browsertest_chromeos.js', @@ -742,7 +742,7 @@ get extraLibraries() { return super.extraLibraries.concat([ '//ui/webui/resources/js/assert.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', 'cups_printer_entry_tests.js', ]); @@ -766,7 +766,7 @@ return super.extraLibraries.concat([ '//ui/webui/resources/js/assert.js', '//ui/webui/resources/js/promise_resolver.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', BROWSER_SETTINGS_PATH + '../fake_chrome_event.js', BROWSER_SETTINGS_PATH + '../chromeos/fake_networking_private.js', @@ -798,7 +798,7 @@ get extraLibraries() { return super.extraLibraries.concat([ '//ui/webui/resources/js/assert.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', 'test_cups_printers_browser_proxy.js', 'cups_printer_page_tests.js', @@ -826,7 +826,7 @@ BROWSER_SETTINGS_PATH + 'fake_language_settings_private.js', BROWSER_SETTINGS_PATH + 'test_languages_browser_proxy.js', BROWSER_SETTINGS_PATH + 'fake_settings_private.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', 'fake_input_method_private.js', 'os_languages_page_tests.js', ]); @@ -854,7 +854,7 @@ return super.extraLibraries.concat([ BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', BROWSER_SETTINGS_PATH + 'test_lifetime_browser_proxy.js', - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', 'test_os_reset_browser_proxy.js', 'os_reset_page_test.js', ]); @@ -899,7 +899,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - BROWSER_SETTINGS_PATH + 'test_util.js', + BROWSER_SETTINGS_PATH + '../test_util.js', BROWSER_SETTINGS_PATH + '../test_browser_proxy.js', 'smb_shares_page_tests.js', ]);
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js index a496156..d972a91c 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui_browsertest.js
@@ -24,7 +24,8 @@ /** @override */ get extraLibraries() { - return super.extraLibraries.concat(BROWSER_SETTINGS_PATH + 'test_util.js'); + return super.extraLibraries.concat( + BROWSER_SETTINGS_PATH + '../test_util.js'); } };
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 36b804a..314373e 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -83,7 +83,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'test_util.js', + '../test_util.js', 'settings_slider_tests.js', ]), }; @@ -207,7 +207,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'test_lifetime_browser_proxy.js', 'test_about_page_browser_proxy.js', @@ -305,8 +305,9 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'passwords_and_autofill_fake_data.js', 'test_util.js', - 'autofill_section_test.js' + 'passwords_and_autofill_fake_data.js', + '../test_util.js', + 'autofill_section_test.js', ]), }; @@ -330,8 +331,9 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'passwords_and_autofill_fake_data.js', 'test_util.js', - 'autofill_section_test.js' + 'passwords_and_autofill_fake_data.js', + '../test_util.js', + 'autofill_section_test.js', ]), }; @@ -364,7 +366,7 @@ 'passwords_and_autofill_fake_data.js', 'passwords_section_test.js', 'test_password_manager_proxy.js', - 'test_util.js', + '../test_util.js', ]), }; @@ -422,7 +424,7 @@ 'passwords_and_autofill_fake_data.js', 'sync_test_util.js', 'test_sync_browser_proxy.js', - 'test_util.js', + '../test_util.js', 'payments_section_test.js', ]), }; @@ -479,9 +481,12 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - '../fake_chrome_event.js', 'chromeos/fake_quick_unlock_private.js', - 'fake_settings_private.js', 'chromeos/fake_quick_unlock_uma.js', - 'chromeos/quick_unlock_authenticate_browsertest_chromeos.js', 'test_util.js' + '../fake_chrome_event.js', + 'chromeos/fake_quick_unlock_private.js', + 'fake_settings_private.js', + 'chromeos/fake_quick_unlock_uma.js', + 'chromeos/quick_unlock_authenticate_browsertest_chromeos.js', + '../test_util.js', ]), }; @@ -775,7 +780,7 @@ '../test_browser_proxy.js', 'sync_test_util.js', 'test_sync_browser_proxy.js', - 'test_util.js', + '../test_util.js', 'people_page_sync_page_test.js', ]), }; @@ -802,7 +807,7 @@ '../test_browser_proxy.js', 'test_lifetime_browser_proxy.js', 'test_reset_browser_proxy.js', - 'test_util.js', + '../test_util.js', 'reset_page_test.js', ]), }; @@ -1057,7 +1062,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../test_browser_proxy.js', - 'test_util.js', + '../test_util.js', 'test_extension_control_browser_proxy.js', 'test_search_engines_browser_proxy.js', 'search_engines_page_test.js', @@ -1089,7 +1094,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'certificate_manager_test.js', ]), @@ -1152,7 +1157,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '//ui/webui/resources/js/promise_resolver.js', - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'test_privacy_page_browser_proxy.js', 'test_sync_browser_proxy.js', @@ -1236,9 +1241,10 @@ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../cr_elements/cr_policy_strings.js', '../test_browser_proxy.js', - 'chooser_exception_list_entry_tests.js', - 'test_site_settings_prefs_browser_proxy.js', + '../test_util.js', 'test_util.js', + 'test_site_settings_prefs_browser_proxy.js', + 'chooser_exception_list_entry_tests.js', ]), }; @@ -1422,6 +1428,7 @@ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../test_browser_proxy.js', 'test_util.js', + '../test_util.js', 'test_site_settings_prefs_browser_proxy.js', 'chromeos/test_multidevice_browser_proxy.js', 'site_list_tests.js', @@ -1457,9 +1464,10 @@ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../cr_elements/cr_policy_strings.js', '../test_browser_proxy.js', - 'site_list_entry_tests.js', + '../test_util.js', 'test_util.js', 'test_site_settings_prefs_browser_proxy.js', + 'site_list_entry_tests.js', ]), }; @@ -1482,6 +1490,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../test_browser_proxy.js', + '../test_util.js', 'test_util.js', 'test_site_settings_prefs_browser_proxy.js', 'zoom_levels_tests.js', @@ -1533,7 +1542,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'security_keys_subpage_test.js', ]), @@ -1555,7 +1564,7 @@ browsePreload: 'chrome://settings/site_settings/site_data.html', extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'test_local_data_browser_proxy.js', 'site_data_test.js', @@ -1842,7 +1851,7 @@ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '//ui/webui/resources/js/promise_resolver.js', '../fake_chrome_event.js', - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'fake_language_settings_private.js', 'fake_settings_private.js', @@ -1871,7 +1880,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../fake_chrome_event.js', - 'test_util.js', + '../test_util.js', '../test_browser_proxy.js', 'fake_settings_private.js', 'fake_language_settings_private.js', @@ -2012,7 +2021,7 @@ /** @override */ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../test_browser_proxy.js', - 'test_util.js', + '../test_util.js', 'settings_main_test.js', ]), }; @@ -2235,7 +2244,7 @@ extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ '../test_browser_proxy.js', 'chromeos/test_multidevice_browser_proxy.js', - 'test_util.js', + '../test_util.js', 'chromeos/multidevice_smartlock_subpage_test.js', ]), };
diff --git a/chrome/test/data/webui/settings/settings_ui_browsertest.js b/chrome/test/data/webui/settings/settings_ui_browsertest.js index ac0a2d8..b71f8f6 100644 --- a/chrome/test/data/webui/settings/settings_ui_browsertest.js +++ b/chrome/test/data/webui/settings/settings_ui_browsertest.js
@@ -17,7 +17,7 @@ /** @override */ extraLibraries: SettingsPageBrowserTest.prototype.extraLibraries.concat([ - 'test_util.js', + '../test_util.js', ]), };
diff --git a/chrome/test/data/webui/settings/test_util.js b/chrome/test/data/webui/settings/test_util.js index cfdce28..7c67808c9 100644 --- a/chrome/test/data/webui/settings/test_util.js +++ b/chrome/test/data/webui/settings/test_util.js
@@ -3,72 +3,6 @@ // found in the LICENSE file. cr.define('test_util', function() { - /** - * Observes an HTML attribute and fires a promise when it matches a given - * value. - * @param {!HTMLElement} target - * @param {string} attributeName - * @param {*} attributeValue - * @return {!Promise} - */ - function whenAttributeIs(target, attributeName, attributeValue) { - function isDone() { - return target.getAttribute(attributeName) == attributeValue; - } - - return isDone() ? Promise.resolve() : new Promise(function(resolve) { - new MutationObserver(function(mutations, observer) { - for (const mutation of mutations) { - assertEquals('attributes', mutation.type); - if (mutation.attributeName == attributeName && isDone()) { - observer.disconnect(); - resolve(); - return; - } - } - }).observe(target, { - attributes: true, - childList: false, - characterData: false - }); - }); - } - - /** - * Converts an event occurrence to a promise. - * @param {string} eventType - * @param {!HTMLElement} target - * @return {!Promise} A promise firing once the event occurs. - */ - function eventToPromise(eventType, target) { - return new Promise(function(resolve, reject) { - target.addEventListener(eventType, function f(e) { - target.removeEventListener(eventType, f); - resolve(e); - }); - }); - } - - /** - * Data-binds two Polymer properties using the property-changed events and - * set/notifyPath API. Useful for testing components which would normally be - * used together. - * @param {!HTMLElement} el1 - * @param {!HTMLElement} el2 - * @param {string} property - */ - function fakeDataBind(el1, el2, property) { - const forwardChange = function(el, event) { - if (event.detail.hasOwnProperty('path')) { - el.notifyPath(event.detail.path, event.detail.value); - } else { - el.set(property, event.detail.value); - } - }; - // Add the listeners symmetrically. Polymer will prevent recursion. - el1.addEventListener(property + '-changed', forwardChange.bind(null, el2)); - el2.addEventListener(property + '-changed', forwardChange.bind(null, el1)); - } /** * Helper to create an object containing a ContentSettingsType key to array or @@ -262,17 +196,6 @@ } } - /** - * Converts beforeNextRender() API to promise-based. - * @param {!Element} element - * @return {!Promise} - */ - function waitForRender(element) { - return new Promise(resolve => { - Polymer.RenderStatus.beforeNextRender(element, resolve); - }); - } - return { createContentSettingTypeToValuePair: createContentSettingTypeToValuePair, createDefaultContentSetting: createDefaultContentSetting, @@ -281,11 +204,7 @@ createRawSiteException: createRawSiteException, createSiteGroup: createSiteGroup, createSiteSettingsPrefs: createSiteSettingsPrefs, - eventToPromise: eventToPromise, - fakeDataBind: fakeDataBind, getContentSettingsTypeFromChooserType: getContentSettingsTypeFromChooserType, - waitForRender: waitForRender, - whenAttributeIs: whenAttributeIs, }; });
diff --git a/chrome/test/data/webui/test_util.js b/chrome/test/data/webui/test_util.js new file mode 100644 index 0000000..ac54ccca --- /dev/null +++ b/chrome/test/data/webui/test_util.js
@@ -0,0 +1,90 @@ +// Copyright 2019 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. + +cr.define('test_util', function() { + /** + * Observes an HTML attribute and fires a promise when it matches a given + * value. + * @param {!HTMLElement} target + * @param {string} attributeName + * @param {*} attributeValue + * @return {!Promise} + */ + function whenAttributeIs(target, attributeName, attributeValue) { + function isDone() { + return target.getAttribute(attributeName) == attributeValue; + } + + return isDone() ? Promise.resolve() : new Promise(function(resolve) { + new MutationObserver(function(mutations, observer) { + for (const mutation of mutations) { + assertEquals('attributes', mutation.type); + if (mutation.attributeName == attributeName && isDone()) { + observer.disconnect(); + resolve(); + return; + } + } + }).observe(target, { + attributes: true, + childList: false, + characterData: false + }); + }); + } + + /** + * Converts an event occurrence to a promise. + * @param {string} eventType + * @param {!HTMLElement} target + * @return {!Promise} A promise firing once the event occurs. + */ + function eventToPromise(eventType, target) { + return new Promise(function(resolve, reject) { + target.addEventListener(eventType, function f(e) { + target.removeEventListener(eventType, f); + resolve(e); + }); + }); + } + + /** + * Data-binds two Polymer properties using the property-changed events and + * set/notifyPath API. Useful for testing components which would normally be + * used together. + * @param {!HTMLElement} el1 + * @param {!HTMLElement} el2 + * @param {string} property + */ + function fakeDataBind(el1, el2, property) { + const forwardChange = function(el, event) { + if (event.detail.hasOwnProperty('path')) { + el.notifyPath(event.detail.path, event.detail.value); + } else { + el.set(property, event.detail.value); + } + }; + // Add the listeners symmetrically. Polymer will prevent recursion. + el1.addEventListener(property + '-changed', forwardChange.bind(null, el2)); + el2.addEventListener(property + '-changed', forwardChange.bind(null, el1)); + } + + /** + * Converts beforeNextRender() API to promise-based. + * @param {!Element} element + * @return {!Promise} + */ + function waitForRender(element) { + return new Promise(resolve => { + Polymer.RenderStatus.beforeNextRender(element, resolve); + }); + } + + return { + eventToPromise: eventToPromise, + fakeDataBind: fakeDataBind, + waitForRender: waitForRender, + whenAttributeIs: whenAttributeIs, + }; +});
diff --git a/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js b/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js index 3d703cef..20e44a8 100644 --- a/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js +++ b/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js
@@ -62,7 +62,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'welcome_app_test.js', 'test_bookmark_proxy.js', 'test_welcome_browser_proxy.js', @@ -107,7 +107,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'navigation_behavior_test.js', ]); } @@ -149,7 +149,7 @@ /** @override */ get extraLibraries() { return super.extraLibraries.concat([ - '../settings/test_util.js', + '../test_util.js', 'nux_set_as_default_test.js', 'test_nux_set_as_default_proxy.js', ]);
diff --git a/chrome/test/data/xr/e2e_test_files/html/test_gamepad_button.html b/chrome/test/data/xr/e2e_test_files/html/test_gamepad_button.html index aeff2f4..e1f89fa7 100644 --- a/chrome/test/data/xr/e2e_test_files/html/test_gamepad_button.html +++ b/chrome/test/data/xr/e2e_test_files/html/test_gamepad_button.html
@@ -42,7 +42,7 @@ frameCounter++; var gp = navigator.getGamepads()[index]; // This can happen if the controller has been briefly disconnected. - if (gp === null) return; + if (gp == null) return; if (!canStartTest) { if (gp.buttons[0].pressed != lastInputValue) { lastInputChangeFrame = frameCounter;
diff --git a/chromecast/media/audio/BUILD.gn b/chromecast/media/audio/BUILD.gn index 788d1c4..b2aab9e2 100644 --- a/chromecast/media/audio/BUILD.gn +++ b/chromecast/media/audio/BUILD.gn
@@ -102,6 +102,7 @@ "MAXIMUM_OUTPUT_BUFFER_SIZE_IN_FRAMES=$maximum_output_buffer_size_in_frames", "DEFAULT_OUTPUT_BUFFER_SIZE_IN_FRAMES=$default_output_buffer_size_in_frames", "ENABLE_AUDIO_CAPTURE_SERVICE=$enable_audio_capture_service", + "USE_UNIX_SOCKETS=$use_unix_sockets", ] if (use_alsa) {
diff --git a/chromecast/media/audio/capture_service/BUILD.gn b/chromecast/media/audio/capture_service/BUILD.gn index 672cd66e..f907f3f 100644 --- a/chromecast/media/audio/capture_service/BUILD.gn +++ b/chromecast/media/audio/capture_service/BUILD.gn
@@ -7,19 +7,10 @@ import("//testing/libfuzzer/fuzzer_test.gni") import("//testing/test.gni") -buildflag_header("buildflags") { - header = "capture_service_buildflags.h" - flags = [ "USE_UNIX_SOCKETS=$use_unix_sockets" ] -} - cast_source_set("common") { sources = [ "constants.h", ] - - deps = [ - ":buildflags", - ] } cast_source_set("receiver") { @@ -35,9 +26,9 @@ ] deps = [ - ":buildflags", "//base", "//chromecast/base", + "//chromecast/media/audio:audio_buildflags", "//chromecast/net:small_message_socket", "//media", "//net",
diff --git a/chromecast/media/audio/capture_service/capture_service_receiver.cc b/chromecast/media/audio/capture_service/capture_service_receiver.cc index 7891ca6..2c0422d 100644 --- a/chromecast/media/audio/capture_service/capture_service_receiver.cc +++ b/chromecast/media/audio/capture_service/capture_service_receiver.cc
@@ -14,7 +14,7 @@ #include "base/message_loop/message_pump_type.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/timer/timer.h" -#include "chromecast/media/audio/capture_service/capture_service_buildflags.h" +#include "chromecast/media/audio/audio_buildflags.h" #include "chromecast/media/audio/capture_service/constants.h" #include "chromecast/media/audio/capture_service/message_parsing_util.h" #include "chromecast/net/small_message_socket.h"
diff --git a/chromecast/media/audio/capture_service/constants.h b/chromecast/media/audio/capture_service/constants.h index 1b98eb5..52d6108 100644 --- a/chromecast/media/audio/capture_service/constants.h +++ b/chromecast/media/audio/capture_service/constants.h
@@ -5,17 +5,12 @@ #ifndef CHROMECAST_MEDIA_AUDIO_CAPTURE_SERVICE_CONSTANTS_H_ #define CHROMECAST_MEDIA_AUDIO_CAPTURE_SERVICE_CONSTANTS_H_ -#include "chromecast/media/audio/capture_service/capture_service_buildflags.h" - namespace chromecast { namespace media { namespace capture_service { -#if BUILDFLAG(USE_UNIX_SOCKETS) constexpr char kDefaultUnixDomainSocketPath[] = "/tmp/capture-service"; -#else constexpr int kDefaultTcpPort = 12855; -#endif enum SampleFormat { INTERLEAVED_INT16 = 0,
diff --git a/chromecast/media/audio/mixer_service/BUILD.gn b/chromecast/media/audio/mixer_service/BUILD.gn index 85aef6b..6728697 100644 --- a/chromecast/media/audio/mixer_service/BUILD.gn +++ b/chromecast/media/audio/mixer_service/BUILD.gn
@@ -13,12 +13,6 @@ ] } -buildflag_header("buildflags") { - header = "mixer_service_buildflags.h" - - flags = [ "USE_UNIX_SOCKETS=$use_unix_sockets" ] -} - cast_source_set("common") { sources = [ "constants.h", @@ -27,7 +21,6 @@ ] deps = [ - ":buildflags", ":proto", "//base", "//chromecast/net:small_message_socket", @@ -44,11 +37,11 @@ ] deps = [ - ":buildflags", ":common", ":proto", "//base", "//chromecast/base", + "//chromecast/media/audio:audio_buildflags", "//chromecast/net:small_message_socket", "//net", ]
diff --git a/chromecast/media/audio/mixer_service/constants.h b/chromecast/media/audio/mixer_service/constants.h index ad73a49a..744add3f 100644 --- a/chromecast/media/audio/mixer_service/constants.h +++ b/chromecast/media/audio/mixer_service/constants.h
@@ -7,17 +7,12 @@ #include <stdint.h> -#include "chromecast/media/audio/mixer_service/mixer_service_buildflags.h" - namespace chromecast { namespace media { namespace mixer_service { -#if BUILDFLAG(USE_UNIX_SOCKETS) constexpr char kDefaultUnixDomainSocketPath[] = "/tmp/mixer-service"; -#else constexpr int kDefaultTcpPort = 12854; -#endif enum class MessageType : int16_t { kMetadata,
diff --git a/chromecast/media/audio/mixer_service/mixer_service_connection.cc b/chromecast/media/audio/mixer_service/mixer_service_connection.cc index 71e945b..84dc8a7 100644 --- a/chromecast/media/audio/mixer_service/mixer_service_connection.cc +++ b/chromecast/media/audio/mixer_service/mixer_service_connection.cc
@@ -16,9 +16,9 @@ #include "base/sequenced_task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "chromecast/base/chromecast_switches.h" +#include "chromecast/media/audio/audio_buildflags.h" #include "chromecast/media/audio/mixer_service/constants.h" #include "chromecast/media/audio/mixer_service/mixer_service.pb.h" -#include "chromecast/media/audio/mixer_service/mixer_service_buildflags.h" #include "chromecast/media/audio/mixer_service/proto_helpers.h" #include "chromecast/net/small_message_socket.h" #include "net/base/address_list.h"
diff --git a/chromecast/renderer/extensions/extension_hooks_delegate.cc b/chromecast/renderer/extensions/extension_hooks_delegate.cc index 862a6260..3e68b62e 100644 --- a/chromecast/renderer/extensions/extension_hooks_delegate.cc +++ b/chromecast/renderer/extensions/extension_hooks_delegate.cc
@@ -21,6 +21,7 @@ #include "extensions/renderer/message_target.h" #include "extensions/renderer/messaging_util.h" #include "extensions/renderer/native_renderer_messaging_service.h" +#include "extensions/renderer/runtime_hooks_delegate.h" #include "extensions/renderer/script_context.h" #include "gin/converter.h" #include "gin/dictionary.h" @@ -237,17 +238,10 @@ RequestResult ExtensionHooksDelegate::HandleGetURL( ScriptContext* script_context, const std::vector<v8::Local<v8::Value>>& arguments) { - DCHECK_EQ(1u, arguments.size()); - DCHECK(arguments[0]->IsString()); - DCHECK(script_context->extension()); - - std::string path = gin::V8ToString(script_context->isolate(), arguments[0]); - - RequestResult result(RequestResult::HANDLED); - result.return_value = - gin::StringToV8(script_context->isolate(), - script_context->extension()->GetResourceURL(path).spec()); - return result; + // We call a static implementation here rather using an alias due to not being + // able to remove the extension.json GetURL entry, as it is used for generated + // documentation and api feature lists some other methods refer to. + return RuntimeHooksDelegate::GetURL(script_context, arguments); } APIBindingHooks::RequestResult ExtensionHooksDelegate::HandleGetViews(
diff --git a/chromeos/components/proximity_auth/unlock_manager_impl.cc b/chromeos/components/proximity_auth/unlock_manager_impl.cc index 610ed3b..60a2cac 100644 --- a/chromeos/components/proximity_auth/unlock_manager_impl.cc +++ b/chromeos/components/proximity_auth/unlock_manager_impl.cc
@@ -43,9 +43,9 @@ // in case something goes wrong. constexpr base::TimeDelta kAuthAttemptTimeout = base::TimeDelta::FromSeconds(5); -constexpr base::TimeDelta kMinGetUnlockableRemoteStatusDuration = +constexpr base::TimeDelta kMinExtendedDuration = base::TimeDelta::FromMilliseconds(1); -constexpr base::TimeDelta kMaxGetUnlockableRemoteStatusDuration = +constexpr base::TimeDelta kMaxExtendedDuration = base::TimeDelta::FromSeconds(15); const int kNumDurationMetricBuckets = 100; @@ -111,6 +111,19 @@ } } +void RecordExtendedDurationTimerMetric(const std::string& histogram_name, + base::TimeDelta duration) { + // Use a custom |max| to account for Smart Lock's timeout (larger than the + // default 10 seconds). + base::UmaHistogramCustomTimes( + histogram_name, duration, kMinExtendedDuration /* min */, + kMaxExtendedDuration /* max */, kNumDurationMetricBuckets /* buckets */); +} + +std::string GetHistogramStatusSuffix(bool unlockable) { + return unlockable ? "Unlockable" : "Other"; +} + } // namespace UnlockManagerImpl::UnlockManagerImpl( @@ -166,20 +179,24 @@ if (life_cycle_) { life_cycle_->AddObserver(this); - attempt_secure_connection_start_time_ = - base::DefaultClock::GetInstance()->Now(); + show_lock_screen_time_ = base::DefaultClock::GetInstance()->Now(); + has_user_been_shown_first_status_ = false; - SetIsPerformingInitialScan(true /* is_performing_initial_scan */); - AttemptToStartRemoteDeviceLifecycle(); + if (IsBluetoothPresentAndPowered()) { + SetIsPerformingInitialScan(true /* is_performing_initial_scan */); + AttemptToStartRemoteDeviceLifecycle(); + } else { + SetIsPerformingInitialScan(false /* is_performing_initial_scan */); + } } else { ResetPerformanceMetricsTimestamps(); if (proximity_monitor_) proximity_monitor_->RemoveObserver(this); proximity_monitor_.reset(); - } - UpdateLockScreen(); + UpdateLockScreen(); + } } void UnlockManagerImpl::OnLifeCycleStateChanged( @@ -238,6 +255,14 @@ remote_screenlock_state_.reset(new RemoteScreenlockState( GetScreenlockStateFromRemoteUpdate(status_update))); + // Only record these metrics within the initial period of opening the laptop + // displaying the lock screen. + if (is_performing_initial_scan_) { + RecordFirstRemoteStatusReceived( + *remote_screenlock_state_ == + RemoteScreenlockState::UNLOCKED /* unlockable */); + } + // This also calls |UpdateLockScreen()| SetIsPerformingInitialScan(false /* is_performing_initial_scan */); } @@ -311,12 +336,14 @@ void UnlockManagerImpl::AdapterPresentChanged(device::BluetoothAdapter* adapter, bool present) { - UpdateLockScreen(); + if (!IsBluetoothAdapterRecoveringFromSuspend()) + OnBluetoothAdapterPresentAndPoweredChanged(); } void UnlockManagerImpl::AdapterPoweredChanged(device::BluetoothAdapter* adapter, bool powered) { - UpdateLockScreen(); + if (!IsBluetoothAdapterRecoveringFromSuspend()) + OnBluetoothAdapterPresentAndPoweredChanged(); } void UnlockManagerImpl::SuspendImminent( @@ -333,10 +360,11 @@ void UnlockManagerImpl::SuspendDone(const base::TimeDelta& sleep_duration) { bluetooth_suspension_recovery_timer_->Start( FROM_HERE, kBluetoothAdapterResumeMaxDuration, - base::Bind(&UnlockManagerImpl::UpdateLockScreen, + base::Bind(&UnlockManagerImpl::OnBluetoothAdapterPresentAndPoweredChanged, weak_ptr_factory_.GetWeakPtr())); - SetIsPerformingInitialScan(true /* is_performing_initial_scan */); + // The next scan after resuming is expected to be triggered by calling + // SetRemoteDeviceLifeCycle(). } bool UnlockManagerImpl::IsBluetoothPresentAndPowered() const { @@ -353,6 +381,18 @@ bluetooth_adapter_->IsPowered(); } +void UnlockManagerImpl::OnBluetoothAdapterPresentAndPoweredChanged() { + DCHECK(!IsBluetoothAdapterRecoveringFromSuspend()); + + if (!IsBluetoothPresentAndPowered()) { + SetIsPerformingInitialScan(false /* is_performing_initial_scan */); + return; + } + + if (!is_performing_initial_scan_) + SetIsPerformingInitialScan(true /* is_performing_initial_scan */); +} + bool UnlockManagerImpl::IsBluetoothAdapterRecoveringFromSuspend() const { return bluetooth_suspension_recovery_timer_->IsRunning(); } @@ -539,8 +579,11 @@ PA_LOG(INFO) << "Updating screenlock state from " << screenlock_state_ << " to " << new_state; - if (new_state == ScreenlockState::AUTHENTICATED) - RecordUnlockableRemoteStatusReceived(); + if (new_state != ScreenlockState::INACTIVE && + new_state != ScreenlockState::BLUETOOTH_CONNECTING) { + RecordFirstStatusShownToUser( + new_state == ScreenlockState::AUTHENTICATED /* unlockable */); + } proximity_auth_client_->UpdateScreenlockState(new_state); screenlock_state_ = new_state; @@ -559,6 +602,9 @@ // Clear the waking up state after a timeout. initial_scan_timeout_weak_ptr_factory_.InvalidateWeakPtrs(); if (is_performing_initial_scan_) { + initial_scan_start_time_ = base::DefaultClock::GetInstance()->Now(); + has_received_first_remote_status_ = false; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&UnlockManagerImpl::OnInitialScanTimeout, @@ -658,39 +704,91 @@ return life_cycle_->GetMessenger(); } -void UnlockManagerImpl::RecordUnlockableRemoteStatusReceived() { - if (attempt_secure_connection_start_time_.is_null() || +void UnlockManagerImpl::RecordFirstRemoteStatusReceived(bool unlockable) { + if (has_received_first_remote_status_) + return; + has_received_first_remote_status_ = true; + + if (initial_scan_start_time_.is_null() || attempt_get_remote_status_start_time_.is_null()) { - PA_LOG(WARNING) << "Attempted to RecordUnlockableRemoteStatusReceived() " + PA_LOG(WARNING) << "Attempted to RecordFirstRemoteStatusReceived() " "without initial timestamps recorded."; NOTREACHED(); + return; } - base::Time now = base::DefaultClock::GetInstance()->Now(); - if (screenlock_type_ == ProximityAuthSystem::SESSION_LOCK) { - // Use a custom |max| to account for Smart Lock's timeout (larger than the - // default 10 seconds). - base::UmaHistogramCustomTimes( - "SmartLock.Performance.StartScanToReceiveUnlockableRemoteStatus." - "Duration.Unlock", - now - attempt_secure_connection_start_time_ /* sample */, - kMinGetUnlockableRemoteStatusDuration /* min */, - kMaxGetUnlockableRemoteStatusDuration /* max */, - kNumDurationMetricBuckets /* buckets */); + const std::string histogram_status_suffix = + GetHistogramStatusSuffix(unlockable); + base::Time now = base::DefaultClock::GetInstance()->Now(); + base::TimeDelta start_scan_to_receive_first_remote_status_duration = + now - initial_scan_start_time_; + base::TimeDelta authentication_to_receive_first_remote_status_duration = + now - attempt_get_remote_status_start_time_; + + if (screenlock_type_ == ProximityAuthSystem::SESSION_LOCK) { + RecordExtendedDurationTimerMetric( + "SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration." + "Unlock", + start_scan_to_receive_first_remote_status_duration); + RecordExtendedDurationTimerMetric( + "SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration." + "Unlock." + + histogram_status_suffix, + start_scan_to_receive_first_remote_status_duration); + + // This should be much less than 10 seconds, so use UmaHistogramTimes. base::UmaHistogramTimes( - "SmartLock.Performance.AuthenticationToReceiveUnlockableRemoteStatus." - "Duration.Unlock", - now - attempt_get_remote_status_start_time_); + "SmartLock.Performance." + "AuthenticationToReceiveFirstRemoteStatusDuration.Unlock", + authentication_to_receive_first_remote_status_duration); + base::UmaHistogramTimes( + "SmartLock.Performance." + "AuthenticationToReceiveFirstRemoteStatusDuration.Unlock." + + histogram_status_suffix, + authentication_to_receive_first_remote_status_duration); } // TODO(crbug.com/905438): Implement similar SignIn metrics. +} - ResetPerformanceMetricsTimestamps(); +void UnlockManagerImpl::RecordFirstStatusShownToUser(bool unlockable) { + if (has_user_been_shown_first_status_) + return; + has_user_been_shown_first_status_ = true; + + if (show_lock_screen_time_.is_null()) { + PA_LOG(WARNING) << "Attempted to RecordFirstStatusShownToUser() " + "without initial timestamp recorded."; + NOTREACHED(); + return; + } + + const std::string histogram_status_suffix = + GetHistogramStatusSuffix(unlockable); + + base::Time now = base::DefaultClock::GetInstance()->Now(); + base::TimeDelta show_lock_screen_to_show_first_status_to_user_duration = + now - show_lock_screen_time_; + + if (screenlock_type_ == ProximityAuthSystem::SESSION_LOCK) { + RecordExtendedDurationTimerMetric( + "SmartLock.Performance.ShowLockScreenToShowFirstStatusToUserDuration." + "Unlock", + show_lock_screen_to_show_first_status_to_user_duration); + RecordExtendedDurationTimerMetric( + "SmartLock.Performance.ShowLockScreenToShowFirstStatusToUserDuration." + "Unlock." + + histogram_status_suffix, + show_lock_screen_to_show_first_status_to_user_duration); + } + + // TODO(crbug.com/905438): Implement similar SignIn metrics. } void UnlockManagerImpl::ResetPerformanceMetricsTimestamps() { - attempt_secure_connection_start_time_ = base::Time(); + show_lock_screen_time_ = base::Time(); + initial_scan_start_time_ = base::Time(); attempt_get_remote_status_start_time_ = base::Time(); }
diff --git a/chromeos/components/proximity_auth/unlock_manager_impl.h b/chromeos/components/proximity_auth/unlock_manager_impl.h index fc52823..1ff97110 100644 --- a/chromeos/components/proximity_auth/unlock_manager_impl.h +++ b/chromeos/components/proximity_auth/unlock_manager_impl.h
@@ -117,6 +117,11 @@ // yet be trusted. bool IsBluetoothAdapterRecoveringFromSuspend() const; + // Called once BluetoothAdapter has recovered after resuming from suspend, + // meaning its presence and power values can be trusted again. This method + // checks if Bluetooth is enabled; if it is not, it cancels the initial scan. + void OnBluetoothAdapterPresentAndPoweredChanged(); + // If the RemoteDeviceLifeCycle is available, ensure it is started (but only // if Bluetooth is available). void AttemptToStartRemoteDeviceLifecycle(); @@ -170,9 +175,13 @@ // yet authenticated. Messenger* GetMessenger(); - // Records UMA performance metrics for the unlockable remote status being - // received. - void RecordUnlockableRemoteStatusReceived(); + // Records UMA performance metrics for the first remote status (regardless of + // whether it's unlockable) being received. + void RecordFirstRemoteStatusReceived(bool unlockable); + + // Records UMA performance metrics for the first status shown to the user + // (regardless of whether it's unlockable/green). + void RecordFirstStatusShownToUser(bool unlockable); // Clears the timers for beginning a scan and fetching remote status. void ResetPerformanceMetricsTimestamps(); @@ -231,13 +240,27 @@ // is fixed. bool was_bluetooth_present_and_powered_before_last_suspend_ = false; + // True only if the remote device has responded with a remote status, either + // "unlockable" or otherwise. + bool has_received_first_remote_status_ = false; + + // True only if the user has been shown a Smart Lock status and tooltip, + // either "unlockable" (green) or otherwise (yellow). + bool has_user_been_shown_first_status_ = false; + // The state of the current screen lock UI. ScreenlockState screenlock_state_ = ScreenlockState::INACTIVE; - // The timestamp of when UnlockManager begins to try to establish a secure - // connection to the requested remote device of the provided - // RemoteDeviceLifeCycle. - base::Time attempt_secure_connection_start_time_; + // The timestamp of when the lock or login screen is shown to the user. Begins + // when the screen is locked, the system is rebooted, the clamshell lid is + // opened, or another user pod is switched to on the login screen. + base::Time show_lock_screen_time_; + + // The timestamp of when UnlockManager begins to perform the initial scan for + // the requested remote device of the provided RemoteDeviceLifeCycle. Usually + // begins right after |show_lock_screen_time_|, unless Bluetooth is disabled. + // If Bluetooth is re-enabled, it also begins. + base::Time initial_scan_start_time_; // The timestamp of when UnlockManager successfully establishes a secure // connection to the requested remote device of the provided
diff --git a/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc b/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc index c06f7e1..e4a962b 100644 --- a/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc +++ b/chromeos/components/proximity_auth/unlock_manager_impl_unittest.cc
@@ -299,18 +299,6 @@ } TEST_F(ProximityAuthUnlockManagerImplTest, - IsUnlockAllowed_SecureChannelNotEstablished) { - CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK); - - life_cycle_.set_messenger(nullptr); - unlock_manager_->SetRemoteDeviceLifeCycle(&life_cycle_); - life_cycle_.ChangeState(RemoteDeviceLifeCycle::State::AUTHENTICATING); - unlock_manager_->OnRemoteStatusUpdate(kRemoteScreenUnlocked); - - EXPECT_FALSE(unlock_manager_->IsUnlockAllowed()); -} - -TEST_F(ProximityAuthUnlockManagerImplTest, IsUnlockAllowed_RemoteDeviceLifeCycleIsNull) { CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK); @@ -628,7 +616,7 @@ } TEST_F(ProximityAuthUnlockManagerImplTest, - BluetoothOffMessagePresentedImmediatelyIfBluetoothWasOffBeforeSuspend) { + BluetoothOffMessageShownImmediatelyIfBluetoothWasOffBeforeSuspend) { CreateUnlockManager(ProximityAuthSystem::SESSION_LOCK); ON_CALL(*bluetooth_adapter_, IsPresent()).WillByDefault(Return(false));
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index 3aa9075f..1fd598e0 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -178,7 +178,10 @@ ImportFormData_ImportCreditCardRecordType_NewCard); FRIEND_TEST_ALL_PREFIXES( FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NoCard_ExpiredCard); + ImportFormData_ImportCreditCardRecordType_NoCard_ExpiredCard_EditableExpDateOff); + FRIEND_TEST_ALL_PREFIXES( + FormDataImporterTest, + ImportFormData_ImportCreditCardRecordType_NewCard_ExpiredCard_WithExpDateFixFlow); FRIEND_TEST_ALL_PREFIXES( FormDataImporterTest, ImportFormData_ImportCreditCardRecordType_NoCard_InvalidCardNumber);
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index 113a581..a672b8a 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -1432,8 +1432,11 @@ ASSERT_EQ(0U, personal_data_manager_->GetCreditCards().size()); } -// Tests that an invalid credit card expiration is not extracted. +// Tests that an invalid credit card expiration is not extracted when the +// expiration date fix flow experiment is disabled. TEST_F(FormDataImporterTest, ImportCreditCard_InvalidExpiryDate) { + scoped_feature_list_.InitAndDisableFeature( + features::kAutofillUpstreamEditableExpirationDate); FormData form; form.url = GURL("https://wwww.foo.com"); @@ -2364,8 +2367,11 @@ } // Ensures that |imported_credit_card_record_type_| is set correctly. -TEST_F(FormDataImporterTest, - ImportFormData_ImportCreditCardRecordType_NoCard_ExpiredCard) { +TEST_F( + FormDataImporterTest, + ImportFormData_ImportCreditCardRecordType_NoCard_ExpiredCard_EditableExpDateOff) { + scoped_feature_list_.InitAndDisableFeature( + features::kAutofillUpstreamEditableExpirationDate); // Simulate a form submission with an expired credit card. FormData form; form.url = GURL("https://wwww.foo.com"); @@ -2388,6 +2394,33 @@ } // Ensures that |imported_credit_card_record_type_| is set correctly. +TEST_F( + FormDataImporterTest, + ImportFormData_ImportCreditCardRecordType_NewCard_ExpiredCard_WithExpDateFixFlow) { + scoped_feature_list_.InitAndEnableFeature( + features::kAutofillUpstreamEditableExpirationDate); + // Simulate a form submission with an expired credit card. + FormData form; + form.url = GURL("https://wwww.foo.com"); + + AddFullCreditCardForm(&form, "Biggie Smalls", "4111 1111 1111 1111", "01", + "1999"); + + FormStructure form_structure(form); + form_structure.DetermineHeuristicTypes(); + std::unique_ptr<CreditCard> imported_credit_card; + EXPECT_TRUE(form_data_importer_->ImportFormData( + form_structure, /*profile_autofill_enabled=*/true, + /*credit_card_autofill_enabled=*/true, + /*should_return_local_card=*/true, &imported_credit_card)); + ASSERT_TRUE(imported_credit_card); + // |imported_credit_card_record_type_| should be NEW_CARD because card was + // successfully imported from the form via the expiration date fix flow. + ASSERT_TRUE(form_data_importer_->imported_credit_card_record_type_ == + FormDataImporter::ImportedCreditCardRecordType::NEW_CARD); +} + +// Ensures that |imported_credit_card_record_type_| is set correctly. TEST_F(FormDataImporterTest, ImportFormData_ImportCreditCardRecordType_NoCard_NoCardOnForm) { // Simulate a form submission with no credit card on form.
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc index 69e6cb6..2a6a856e 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -2964,7 +2964,37 @@ } TEST_F(CreditCardSaveManagerTest, - UploadCreditCard_RequestExpirationDateIfTestingExperimentOn) { + UploadCreditCard_DoNotRequestExpirationDate_EditableExpDateOff) { + scoped_feature_list_.InitAndDisableFeature( + features::kAutofillUpstreamEditableExpirationDate); + // Create, fill and submit an address form in order to establish a recent + // profile which can be selected for the upload request. + FormData address_form; + test::CreateTestAddressFormData(&address_form); + FormsSeen(std::vector<FormData>(1, address_form)); + ManuallyFillAddressForm("John", "Smith", "77401", "US", &address_form); + FormSubmitted(address_form); + + // Set up our credit card form data. + FormData credit_card_form; + CreateTestCreditCardFormData(&credit_card_form, CreditCardFormOptions()); + FormsSeen(std::vector<FormData>(1, credit_card_form)); + + // Edit the data, and submit. + credit_card_form.fields[0].value = ASCIIToUTF16("John Smith"); + credit_card_form.fields[1].value = ASCIIToUTF16("4111111111111111"); + credit_card_form.fields[2].value = ASCIIToUTF16(""); + credit_card_form.fields[3].value = ASCIIToUTF16(""); + credit_card_form.fields[4].value = ASCIIToUTF16("123"); + + base::HistogramTester histogram_tester; + FormSubmitted(credit_card_form); + EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled()); + EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded()); +} + +TEST_F(CreditCardSaveManagerTest, + UploadCreditCard_RequestExpirationDateViaExpDateFixFlow) { scoped_feature_list_.InitAndEnableFeature( features::kAutofillUpstreamEditableExpirationDate); // Create, fill and submit an address form in order to establish a recent @@ -3180,7 +3210,7 @@ } TEST_F(CreditCardSaveManagerTest, - UploadCreditCard_RequestCardholderNameIfTestingExperimentOn) { + UploadCreditCard_RequestCardholderNameViaNameFixFlow) { scoped_feature_list_.InitAndEnableFeature( features::kAutofillUpstreamAlwaysRequestCardholderName);
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index bd755582..ed1add6f 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -159,8 +159,13 @@ }; const base::Feature kAutofillUpstreamEditableExpirationDate{ - "AutofillUpstreamEditableExpirationDate", - base::FEATURE_DISABLED_BY_DEFAULT}; + "AutofillUpstreamEditableExpirationDate", +#if defined(OS_ANDROID) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; bool ShouldShowImprovedUserConsentForCreditCardSave() { #if defined(OS_WIN) || defined(OS_MACOSX) || \
diff --git a/components/feed/core/feed_content_database.cc b/components/feed/core/feed_content_database.cc index da4d432..5b452c56 100644 --- a/components/feed/core/feed_content_database.cc +++ b/components/feed/core/feed_content_database.cc
@@ -22,9 +22,6 @@ namespace { -using StorageEntryVector = - leveldb_proto::ProtoDatabase<ContentStorageProto>::KeyEntryVector; - const char kContentDatabaseFolder[] = "content"; const size_t kDatabaseWriteBufferSizeBytes = 64 * 1024; // 64KB @@ -51,19 +48,38 @@ FeedContentDatabase::FeedContentDatabase( leveldb_proto::ProtoDatabaseProvider* proto_database_provider, const base::FilePath& database_folder) - : FeedContentDatabase(proto_database_provider->GetDB<ContentStorageProto>( + : database_status_(InitStatus::kNotInitialized), + task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE})), + storage_database_(proto_database_provider->GetDB<ContentStorageProto>( leveldb_proto::ProtoDbType::FEED_CONTENT_DATABASE, database_folder.AppendASCII(kContentDatabaseFolder), - base::CreateSequencedTaskRunner( - {base::ThreadPool(), base::MayBlock(), - base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}))) {} + task_runner_)) { + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&FeedContentDatabase::InitInternal, + weak_ptr_factory_.GetWeakPtr())); +} +// Used for testing. FeedContentDatabase::FeedContentDatabase( std::unique_ptr<leveldb_proto::ProtoDatabase<ContentStorageProto>> - storage_database) + storage_database, + scoped_refptr<base::SequencedTaskRunner> task_runner) : database_status_(InitStatus::kNotInitialized), + task_runner_(task_runner), storage_database_(std::move(storage_database)) { + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&FeedContentDatabase::InitInternal, + weak_ptr_factory_.GetWeakPtr())); +} + +FeedContentDatabase::~FeedContentDatabase() = default; + +bool FeedContentDatabase::IsInitialized() const { + return database_status_ == InitStatus::kOK; +} + +void FeedContentDatabase::InitInternal() { leveldb_env::Options options = leveldb_proto::CreateSimpleOptions(); options.write_buffer_size = base::SysInfo::IsLowEndDevice() ? kDatabaseWriteBufferSizeBytesForLowEndDevice @@ -74,41 +90,48 @@ weak_ptr_factory_.GetWeakPtr())); } -FeedContentDatabase::~FeedContentDatabase() = default; - -bool FeedContentDatabase::IsInitialized() const { - return database_status_ == InitStatus::kOK; -} - void FeedContentDatabase::LoadContent(const std::vector<std::string>& keys, ContentLoadCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - std::unordered_set<std::string> key_set(keys.begin(), keys.end()); - storage_database_->LoadEntriesWithFilter( - base::BindRepeating(&DatabaseKeyFilter, std::move(key_set)), - CreateReadOptions(), /* target_prefix */ "", - base::BindOnce(&FeedContentDatabase::OnLoadEntriesForLoadContent, - weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), - std::move(callback))); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedContentDatabase::LoadEntriesWithFilterInternal, + weak_ptr_factory_.GetWeakPtr(), + base::BindRepeating(&DatabaseKeyFilter, std::move(key_set)), + std::move(callback))); } void FeedContentDatabase::LoadContentByPrefix(const std::string& prefix, ContentLoadCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedContentDatabase::LoadEntriesWithFilterInternal, + weak_ptr_factory_.GetWeakPtr(), + base::BindRepeating(&DatabasePrefixFilter, std::move(prefix)), + std::move(callback))); +} +void FeedContentDatabase::LoadEntriesWithFilterInternal( + const leveldb_proto::KeyFilter& key_filter, + ContentLoadCallback callback) { storage_database_->LoadEntriesWithFilter( - base::BindRepeating(&DatabasePrefixFilter, std::move(prefix)), - CreateReadOptions(), /* target_prefix */ "", + std::move(key_filter), CreateReadOptions(), /* target_prefix */ "", base::BindOnce(&FeedContentDatabase::OnLoadEntriesForLoadContent, weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), std::move(callback))); } void FeedContentDatabase::LoadAllContentKeys(ContentKeyCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FeedContentDatabase::LoadKeysInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} +void FeedContentDatabase::LoadKeysInternal(ContentKeyCallback callback) { storage_database_->LoadKeys( base::BindOnce(&FeedContentDatabase::OnLoadKeysForLoadAllContentKeys, weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), @@ -118,7 +141,6 @@ void FeedContentDatabase::CommitContentMutation( std::unique_ptr<ContentMutation> content_mutation, ConfirmationCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(content_mutation); UMA_HISTOGRAM_COUNTS_100( @@ -126,8 +148,8 @@ content_mutation->Size()); if (content_mutation->Empty()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), true)); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), true)); return; } @@ -164,8 +186,8 @@ break; default: // Operation type is not supported, therefore failing immediately. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), false)); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), false)); } } @@ -181,10 +203,12 @@ proto.set_content_data(operation.value()); contents_to_save->emplace_back(proto.key(), std::move(proto)); - storage_database_->UpdateEntries( - std::move(contents_to_save), std::make_unique<std::vector<std::string>>(), - base::BindOnce(&FeedContentDatabase::OnOperationCommitted, + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FeedContentDatabase::UpdateEntriesInternal, weak_ptr_factory_.GetWeakPtr(), + std::move(contents_to_save), + std::make_unique<std::vector<std::string>>(), std::move(content_mutation), std::move(callback))); } @@ -197,8 +221,22 @@ auto content_to_delete = std::make_unique<std::vector<std::string>>( std::initializer_list<std::string>({operation.key()})); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FeedContentDatabase::UpdateEntriesInternal, + weak_ptr_factory_.GetWeakPtr(), + std::make_unique<StorageEntryVector>(), + std::move(content_to_delete), std::move(content_mutation), + std::move(callback))); +} + +void FeedContentDatabase::UpdateEntriesInternal( + std::unique_ptr<StorageEntryVector> entries_to_save, + std::unique_ptr<std::vector<std::string>> keys_to_remove, + std::unique_ptr<ContentMutation> content_mutation, + ConfirmationCallback callback) { storage_database_->UpdateEntries( - std::make_unique<StorageEntryVector>(), std::move(content_to_delete), + std::move(entries_to_save), std::move(keys_to_remove), base::BindOnce(&FeedContentDatabase::OnOperationCommitted, weak_ptr_factory_.GetWeakPtr(), std::move(content_mutation), std::move(callback))); @@ -210,12 +248,13 @@ ConfirmationCallback callback) { DCHECK_EQ(operation.type(), ContentOperation::CONTENT_DELETE_BY_PREFIX); - storage_database_->UpdateEntriesWithRemoveFilter( - std::make_unique<StorageEntryVector>(), - base::BindRepeating(&DatabasePrefixFilter, operation.prefix()), - base::BindOnce(&FeedContentDatabase::OnOperationCommitted, - weak_ptr_factory_.GetWeakPtr(), - std::move(content_mutation), std::move(callback))); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedContentDatabase::UpdateEntriesWithRemoveFilterInternal, + weak_ptr_factory_.GetWeakPtr(), + base::BindRepeating(&DatabasePrefixFilter, operation.prefix()), + std::move(content_mutation), std::move(callback))); } void FeedContentDatabase::DeleteAllContent( @@ -225,9 +264,21 @@ DCHECK_EQ(operation.type(), ContentOperation::CONTENT_DELETE_ALL); std::string key_prefix = ""; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedContentDatabase::UpdateEntriesWithRemoveFilterInternal, + weak_ptr_factory_.GetWeakPtr(), + base::BindRepeating(&DatabasePrefixFilter, std::move(key_prefix)), + std::move(content_mutation), std::move(callback))); +} + +void FeedContentDatabase::UpdateEntriesWithRemoveFilterInternal( + const leveldb_proto::KeyFilter& key_filter, + std::unique_ptr<ContentMutation> content_mutation, + ConfirmationCallback callback) { storage_database_->UpdateEntriesWithRemoveFilter( - std::make_unique<StorageEntryVector>(), - base::BindRepeating(&DatabasePrefixFilter, std::move(key_prefix)), + std::make_unique<StorageEntryVector>(), std::move(key_filter), base::BindOnce(&FeedContentDatabase::OnOperationCommitted, weak_ptr_factory_.GetWeakPtr(), std::move(content_mutation), std::move(callback)));
diff --git a/components/feed/core/feed_content_database.h b/components/feed/core/feed_content_database.h index 6223adf..0d951f3 100644 --- a/components/feed/core/feed_content_database.h +++ b/components/feed/core/feed_content_database.h
@@ -27,7 +27,9 @@ using InitStatus = leveldb_proto::Enums::InitStatus; // FeedContentDatabase is leveldb backend store for Feed's content storage data. -// Feed's content data are key-value pairs. +// Feed's content data are key-value pairs. In order to support callers from +// different threads, this class posts all database operations to an owned +// sequenced task runner. class FeedContentDatabase { public: using KeyAndData = std::pair<std::string, std::string>; @@ -46,6 +48,9 @@ // the entry's existence. using ConfirmationCallback = base::OnceCallback<void(bool)>; + using StorageEntryVector = + leveldb_proto::ProtoDatabase<ContentStorageProto>::KeyEntryVector; + // Initializes the database with |proto_database_provider| and // |database_folder|. FeedContentDatabase( @@ -56,7 +61,8 @@ // Useful for testing. explicit FeedContentDatabase( std::unique_ptr<leveldb_proto::ProtoDatabase<ContentStorageProto>> - storage_database); + storage_database, + scoped_refptr<base::SequencedTaskRunner> task_runner); ~FeedContentDatabase(); @@ -102,6 +108,21 @@ std::unique_ptr<ContentMutation> content_mutation, ConfirmationCallback callback); + // The following *Internal methods must be executed from |task_runner_|. + void InitInternal(); + void LoadEntriesWithFilterInternal(const leveldb_proto::KeyFilter& key_filter, + ContentLoadCallback callback); + void LoadKeysInternal(ContentKeyCallback callback); + void UpdateEntriesInternal( + std::unique_ptr<StorageEntryVector> entries_to_save, + std::unique_ptr<std::vector<std::string>> keys_to_remove, + std::unique_ptr<ContentMutation> content_mutation, + ConfirmationCallback callback); + void UpdateEntriesWithRemoveFilterInternal( + const leveldb_proto::KeyFilter& key_filter, + std::unique_ptr<ContentMutation> content_mutation, + ConfirmationCallback callback); + // Callback methods given to |storage_database_| for async responses. void OnDatabaseInitialized(InitStatus status); void OnLoadEntriesForLoadContent( @@ -121,12 +142,13 @@ // Status of the database initialization. InitStatus database_status_; + // Task runner on which to execute database calls. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // The database for storing content storage information. std::unique_ptr<leveldb_proto::ProtoDatabase<ContentStorageProto>> storage_database_; - SEQUENCE_CHECKER(sequence_checker_); - base::WeakPtrFactory<FeedContentDatabase> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(FeedContentDatabase);
diff --git a/components/feed/core/feed_content_database_unittest.cc b/components/feed/core/feed_content_database_unittest.cc index a739f003..f154aace 100644 --- a/components/feed/core/feed_content_database_unittest.cc +++ b/components/feed/core/feed_content_database_unittest.cc
@@ -57,10 +57,14 @@ auto storage_db = std::make_unique<FakeDB<ContentStorageProto>>(&content_db_storage_); + task_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); + content_db_ = storage_db.get(); - feed_db_ = std::make_unique<FeedContentDatabase>(std::move(storage_db)); + feed_db_ = std::make_unique<FeedContentDatabase>(std::move(storage_db), + task_runner_); if (init_database) { - content_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); + InitStatusCallback(content_db_, leveldb_proto::Enums::InitStatus::kOK); ASSERT_TRUE(db()->IsInitialized()); } } @@ -73,8 +77,55 @@ content_db_storage_[key] = storage_proto; } + // Since the FakeDB implementation doesn't run callbacks on the same task + // runner as the original request was made (like the real ProtoDatabase impl + // does), we explicitly post all callbacks onto the DB task runner here. + void InitStatusCallback(FakeDB<ContentStorageProto>* storage_db, + leveldb_proto::Enums::InitStatus status) { + task_runner()->PostTask(FROM_HERE, + base::BindOnce( + [](FakeDB<ContentStorageProto>* storage_db, + leveldb_proto::Enums::InitStatus status) { + storage_db->InitStatusCallback(status); + }, + storage_db, status)); + RunUntilIdle(); + } + void LoadCallback(FakeDB<ContentStorageProto>* storage_db, bool success) { + task_runner()->PostTask( + FROM_HERE, + base::BindOnce([](FakeDB<ContentStorageProto>* storage_db, + bool success) { storage_db->LoadCallback(success); }, + storage_db, success)); + RunUntilIdle(); + } + void LoadKeysCallback(FakeDB<ContentStorageProto>* storage_db, bool success) { + task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + [](FakeDB<ContentStorageProto>* storage_db, bool success) { + storage_db->LoadKeysCallback(success); + }, + storage_db, success)); + RunUntilIdle(); + } + void UpdateCallback(FakeDB<ContentStorageProto>* storage_db, bool success) { + task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + [](FakeDB<ContentStorageProto>* storage_db, bool success) { + storage_db->UpdateCallback(success); + }, + storage_db, success)); + RunUntilIdle(); + } + void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } + scoped_refptr<base::SequencedTaskRunner> task_runner() { + return task_runner_; + } + FakeDB<ContentStorageProto>* storage_db() { return content_db_; } FeedContentDatabase* db() { return feed_db_.get(); } @@ -91,6 +142,8 @@ std::map<std::string, ContentStorageProto> content_db_storage_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // Owned by |feed_db_|. FakeDB<ContentStorageProto>* content_db_; @@ -106,7 +159,8 @@ CreateDatabase(/*init_database=*/false); - storage_db()->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); + InitStatusCallback(storage_db(), leveldb_proto::Enums::InitStatus::kOK); + EXPECT_TRUE(db()->IsInitialized()); } @@ -118,7 +172,7 @@ {kContentKey1}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -144,7 +198,7 @@ {kContentKey2, kContentKey3}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -172,7 +226,7 @@ kContentKeyPrefix, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -193,7 +247,7 @@ }); db()->LoadAllContentKeys(base::BindOnce( &FeedContentDatabaseTest::OnContentKeyReceived, base::Unretained(this))); - storage_db()->LoadKeysCallback(true); + LoadKeysCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaSizeHistogramName, /*size=*/2, 1); @@ -213,8 +267,8 @@ std::move(content_mutation), base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->UpdateCallback(true); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); + UpdateCallback(storage_db(), true); // Make sure they're there. EXPECT_CALL(*this, OnContentEntriesReceived(_, _)) @@ -231,7 +285,7 @@ {kContentKey1, kContentKey2}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/2, 1); @@ -255,8 +309,8 @@ std::move(content_mutation), base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->UpdateCallback(true); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); + UpdateCallback(storage_db(), true); // Make sure only |kContentKey2| got deleted. EXPECT_CALL(*this, OnContentEntriesReceived(_, _)) @@ -271,7 +325,7 @@ {kContentKey1, kContentKey2}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/2, 1); @@ -294,7 +348,7 @@ std::move(content_mutation), base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); // Make sure |kContentKey1| and |kContentKey2| got deleted. EXPECT_CALL(*this, OnContentEntriesReceived(_, _)) @@ -307,7 +361,7 @@ {kContentKey1, kContentKey2}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/1, 1); @@ -331,7 +385,7 @@ std::move(content_mutation), base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); // Make sure |kContentKey1| and |kContentKey2| got deleted. EXPECT_CALL(*this, OnContentEntriesReceived(_, _)) @@ -344,7 +398,7 @@ {kContentKey1, kContentKey2}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/1, 1); @@ -366,10 +420,10 @@ std::move(content_mutation), base::BindOnce(&FeedContentDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->UpdateCallback(true); - storage_db()->UpdateCallback(true); - storage_db()->UpdateCallback(true); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); + UpdateCallback(storage_db(), true); + UpdateCallback(storage_db(), true); + UpdateCallback(storage_db(), true); // Make sure only |kContentKey2| got deleted. EXPECT_CALL(*this, OnContentEntriesReceived(_, _)) @@ -384,7 +438,7 @@ {kContentKey1, kContentKey2}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(true); + LoadCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/4, 1); @@ -408,7 +462,7 @@ {kContentKey2, kContentKey3}, base::BindOnce(&FeedContentDatabaseTest::OnContentEntriesReceived, base::Unretained(this))); - storage_db()->LoadCallback(false); + LoadCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -426,7 +480,7 @@ }); db()->LoadAllContentKeys(base::BindOnce( &FeedContentDatabaseTest::OnContentKeyReceived, base::Unretained(this))); - storage_db()->LoadKeysCallback(false); + LoadKeysCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaSizeHistogramName, 0); histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1);
diff --git a/components/feed/core/feed_journal_database.cc b/components/feed/core/feed_journal_database.cc index 0030fad..1903ee1 100644 --- a/components/feed/core/feed_journal_database.cc +++ b/components/feed/core/feed_journal_database.cc
@@ -20,9 +20,6 @@ namespace { -using StorageEntryVector = - leveldb_proto::ProtoDatabase<JournalStorageProto>::KeyEntryVector; - const char kJournalDatabaseFolder[] = "journal"; const size_t kDatabaseWriteBufferSizeBytes = 64 * 1024; // 64KB @@ -39,19 +36,38 @@ FeedJournalDatabase::FeedJournalDatabase( leveldb_proto::ProtoDatabaseProvider* proto_database_provider, const base::FilePath& database_folder) - : FeedJournalDatabase(proto_database_provider->GetDB<JournalStorageProto>( + : database_status_(InitStatus::kNotInitialized), + task_runner_(base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE})), + storage_database_(proto_database_provider->GetDB<JournalStorageProto>( leveldb_proto::ProtoDbType::FEED_JOURNAL_DATABASE, database_folder.AppendASCII(kJournalDatabaseFolder), - base::CreateSequencedTaskRunner( - {base::ThreadPool(), base::MayBlock(), - base::TaskPriority::BEST_EFFORT, - base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}))) {} + task_runner_)) { + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&FeedJournalDatabase::InitInternal, + weak_ptr_factory_.GetWeakPtr())); +} +// Used for testing. FeedJournalDatabase::FeedJournalDatabase( std::unique_ptr<leveldb_proto::ProtoDatabase<JournalStorageProto>> - storage_database) + storage_database, + scoped_refptr<base::SequencedTaskRunner> task_runner) : database_status_(InitStatus::kNotInitialized), + task_runner_(task_runner), storage_database_(std::move(storage_database)) { + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&FeedJournalDatabase::InitInternal, + weak_ptr_factory_.GetWeakPtr())); +} + +FeedJournalDatabase::~FeedJournalDatabase() = default; + +bool FeedJournalDatabase::IsInitialized() const { + return database_status_ == InitStatus::kOK; +} + +void FeedJournalDatabase::InitInternal() { leveldb_env::Options options = leveldb_proto::CreateSimpleOptions(); options.write_buffer_size = base::SysInfo::IsLowEndDevice() ? kDatabaseWriteBufferSizeBytesForLowEndDevice @@ -62,36 +78,33 @@ weak_ptr_factory_.GetWeakPtr())); } -FeedJournalDatabase::~FeedJournalDatabase() = default; - -bool FeedJournalDatabase::IsInitialized() const { - return database_status_ == InitStatus::kOK; -} - void FeedJournalDatabase::LoadJournal(const std::string& key, JournalLoadCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - storage_database_->GetEntry( - key, base::BindOnce(&FeedJournalDatabase::OnGetEntryForLoadJournal, - weak_ptr_factory_.GetWeakPtr(), - base::TimeTicks::Now(), std::move(callback))); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedJournalDatabase::GetEntryInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(key), + base::BindOnce(&FeedJournalDatabase::OnGetEntryForLoadJournal, + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), + std::move(callback)))); } void FeedJournalDatabase::DoesJournalExist(const std::string& key, CheckExistingCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - storage_database_->GetEntry( - key, base::BindOnce(&FeedJournalDatabase::OnGetEntryForDoesJournalExist, - weak_ptr_factory_.GetWeakPtr(), - base::TimeTicks::Now(), std::move(callback))); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedJournalDatabase::GetEntryInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(key), + base::BindOnce(&FeedJournalDatabase::OnGetEntryForDoesJournalExist, + weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), + std::move(callback)))); } void FeedJournalDatabase::CommitJournalMutation( std::unique_ptr<JournalMutation> journal_mutation, ConfirmationCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(journal_mutation); UMA_HISTOGRAM_COUNTS_100( @@ -99,15 +112,15 @@ journal_mutation->Size()); if (journal_mutation->Empty()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(std::move(callback), true)); + task_runner_->PostTask(FROM_HERE, + base::BindOnce(std::move(callback), true)); return; } // Skip loading journal if the first operation is JOURNAL_DELETE. if (journal_mutation->FirstOperationType() == JournalOperation::JOURNAL_DELETE) { - base::ThreadTaskRunnerHandle::Get()->PostTask( + task_runner_->PostTask( FROM_HERE, base::BindOnce(&FeedJournalDatabase::PerformOperations, weak_ptr_factory_.GetWeakPtr(), nullptr, @@ -116,16 +129,32 @@ } std::string journal_name = journal_mutation->journal_name(); - storage_database_->GetEntry( - journal_name, - base::BindOnce(&FeedJournalDatabase::OnGetEntryForCommitJournalMutation, - weak_ptr_factory_.GetWeakPtr(), - std::move(journal_mutation), std::move(callback))); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &FeedJournalDatabase::GetEntryInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(journal_name), + base::BindOnce( + &FeedJournalDatabase::OnGetEntryForCommitJournalMutation, + weak_ptr_factory_.GetWeakPtr(), std::move(journal_mutation), + std::move(callback)))); +} + +void FeedJournalDatabase::GetEntryInternal( + const std::string& key, + leveldb_proto::Callbacks::Internal<JournalStorageProto>::GetCallback + callback) { + storage_database_->GetEntry(key, std::move(callback)); } void FeedJournalDatabase::LoadAllJournalKeys(JournalLoadCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FeedJournalDatabase::LoadKeysInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} +void FeedJournalDatabase::LoadKeysInternal(JournalLoadCallback callback) { storage_database_->LoadKeys( base::BindOnce(&FeedJournalDatabase::OnLoadKeysForLoadAllJournalKeys, weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), @@ -133,8 +162,14 @@ } void FeedJournalDatabase::DeleteAllJournals(ConfirmationCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FeedJournalDatabase::DeleteAllEntriesInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); +} +void FeedJournalDatabase::DeleteAllEntriesInternal( + ConfirmationCallback callback) { // For deleting all, filter method always return true. storage_database_->UpdateEntriesWithRemoveFilter( std::make_unique<StorageEntryVector>(), @@ -198,8 +233,21 @@ journals_to_save->emplace_back(it->first, std::move(it->second)); } + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&FeedJournalDatabase::UpdateEntriesInternal, + weak_ptr_factory_.GetWeakPtr(), + std::move(journals_to_save), std::move(journals_to_delete), + std::move(start_time), std::move(callback))); +} + +void FeedJournalDatabase::UpdateEntriesInternal( + std::unique_ptr<StorageEntryVector> entries_to_save, + std::unique_ptr<std::vector<std::string>> keys_to_remove, + base::TimeTicks start_time, + ConfirmationCallback callback) { storage_database_->UpdateEntries( - std::move(journals_to_save), std::move(journals_to_delete), + std::move(entries_to_save), std::move(keys_to_remove), base::BindOnce(&FeedJournalDatabase::OnOperationCommitted, weak_ptr_factory_.GetWeakPtr(), std::move(start_time), std::move(callback)));
diff --git a/components/feed/core/feed_journal_database.h b/components/feed/core/feed_journal_database.h index 4ded367..f79cd06 100644 --- a/components/feed/core/feed_journal_database.h +++ b/components/feed/core/feed_journal_database.h
@@ -29,7 +29,9 @@ using InitStatus = leveldb_proto::Enums::InitStatus; // FeedJournalDatabase is leveldb backend store for Feed's journal storage data. -// Feed's journal data are key-value pairs. +// Feed's journal data are key-value pairs. In order to support callers from +// different threads, this class posts all database operations to an owned +// sequenced task runner. class FeedJournalDatabase { public: // Returns the journal data as a vector of strings when calling loading data @@ -47,6 +49,9 @@ using JournalMap = base::flat_map<std::string, JournalStorageProto>; + using StorageEntryVector = + leveldb_proto::ProtoDatabase<JournalStorageProto>::KeyEntryVector; + // Initializes the database with |proto_database_provider| and // |database_folder|. FeedJournalDatabase( @@ -57,7 +62,8 @@ // Useful for testing. explicit FeedJournalDatabase( std::unique_ptr<leveldb_proto::ProtoDatabase<JournalStorageProto>> - storage_database); + storage_database, + scoped_refptr<base::SequencedTaskRunner> task_runner); ~FeedJournalDatabase(); @@ -88,9 +94,9 @@ private: // This method performs JournalOperation in the |journal_mutation|. - // If the first operation in |journal_mutation| is JOURNAL_DELETE, journal can - // be empty, otherwise we need to load |journal| from database and then pass - // to this method. + // If the first operation in |journal_mutation| is JOURNAL_DELETE, journal + // can be empty, otherwise we need to load |journal| from database and + // then pass to this method. void PerformOperations(std::unique_ptr<JournalStorageProto> journal, std::unique_ptr<JournalMutation> journal_mutation, ConfirmationCallback callback); @@ -99,6 +105,20 @@ JournalMap copy_to_journal, ConfirmationCallback callback); + // The following *Internal methods must be executed from |task_runner_|. + void InitInternal(); + void GetEntryInternal( + const std::string& key, + leveldb_proto::Callbacks::Internal<JournalStorageProto>::GetCallback + callback); + void LoadKeysInternal(JournalLoadCallback callback); + void DeleteAllEntriesInternal(ConfirmationCallback callback); + void UpdateEntriesInternal( + std::unique_ptr<StorageEntryVector> entries_to_save, + std::unique_ptr<std::vector<std::string>> keys_to_remove, + base::TimeTicks start_time, + ConfirmationCallback callback); + // Callback methods given to |storage_database_| for async responses. void OnDatabaseInitialized(InitStatus status); void OnGetEntryForLoadJournal(base::TimeTicks start_time, @@ -130,12 +150,13 @@ // Status of the database initialization. InitStatus database_status_; + // Task runner on which to execute database calls. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // The database for storing journal storage information. std::unique_ptr<leveldb_proto::ProtoDatabase<JournalStorageProto>> storage_database_; - SEQUENCE_CHECKER(sequence_checker_); - base::WeakPtrFactory<FeedJournalDatabase> weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(FeedJournalDatabase);
diff --git a/components/feed/core/feed_journal_database_unittest.cc b/components/feed/core/feed_journal_database_unittest.cc index 172d2d16..7bb4a06b 100644 --- a/components/feed/core/feed_journal_database_unittest.cc +++ b/components/feed/core/feed_journal_database_unittest.cc
@@ -63,10 +63,14 @@ auto storage_db = std::make_unique<FakeDB<JournalStorageProto>>(&journal_db_storage_); + task_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); + journal_db_ = storage_db.get(); - feed_db_ = std::make_unique<FeedJournalDatabase>(std::move(storage_db)); + feed_db_ = std::make_unique<FeedJournalDatabase>(std::move(storage_db), + task_runner_); if (init_database) { - journal_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); + InitStatusCallback(journal_db_, leveldb_proto::Enums::InitStatus::kOK); ASSERT_TRUE(db()->IsInitialized()); } } @@ -81,8 +85,55 @@ journal_db_storage_[key] = storage_proto; } + // Since the FakeDB implementation doesn't run callbacks on the same task + // runner as the original request was made (like the real ProtoDatabase impl + // does), we explicitly post all callbacks onto the DB task runner here. + void InitStatusCallback(FakeDB<JournalStorageProto>* storage_db, + leveldb_proto::Enums::InitStatus status) { + task_runner()->PostTask(FROM_HERE, + base::BindOnce( + [](FakeDB<JournalStorageProto>* storage_db, + leveldb_proto::Enums::InitStatus status) { + storage_db->InitStatusCallback(status); + }, + storage_db, status)); + RunUntilIdle(); + } + void GetCallback(FakeDB<JournalStorageProto>* storage_db, bool success) { + task_runner()->PostTask( + FROM_HERE, + base::BindOnce([](FakeDB<JournalStorageProto>* storage_db, + bool success) { storage_db->GetCallback(success); }, + storage_db, success)); + RunUntilIdle(); + } + void LoadKeysCallback(FakeDB<JournalStorageProto>* storage_db, bool success) { + task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + [](FakeDB<JournalStorageProto>* storage_db, bool success) { + storage_db->LoadKeysCallback(success); + }, + storage_db, success)); + RunUntilIdle(); + } + void UpdateCallback(FakeDB<JournalStorageProto>* storage_db, bool success) { + task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + [](FakeDB<JournalStorageProto>* storage_db, bool success) { + storage_db->UpdateCallback(success); + }, + storage_db, success)); + RunUntilIdle(); + } + void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } + scoped_refptr<base::SequencedTaskRunner> task_runner() { + return task_runner_; + } + FakeDB<JournalStorageProto>* storage_db() { return journal_db_; } FeedJournalDatabase* db() { return feed_db_.get(); } @@ -98,6 +149,8 @@ std::map<std::string, JournalStorageProto> journal_db_storage_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // Owned by |feed_db_|. FakeDB<JournalStorageProto>* journal_db_; @@ -114,7 +167,7 @@ CreateDatabase(/*init_database=*/false); EXPECT_FALSE(db()->IsInitialized()); - storage_db()->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); + InitStatusCallback(storage_db(), leveldb_proto::Enums::InitStatus::kOK); EXPECT_TRUE(db()->IsInitialized()); } @@ -140,7 +193,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -159,7 +212,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -176,8 +229,8 @@ std::move(journal_mutation), base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->GetCallback(true); - storage_db()->UpdateCallback(true); + GetCallback(storage_db(), true); + UpdateCallback(storage_db(), true); // Make sure they're there. EXPECT_CALL(*this, OnJournalEntryReceived(_, _)) @@ -191,7 +244,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/2, 1); @@ -209,8 +262,8 @@ std::move(journal_mutation), base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->GetCallback(true); - storage_db()->UpdateCallback(true); + GetCallback(storage_db(), true); + UpdateCallback(storage_db(), true); // Check new instances are there. EXPECT_CALL(*this, OnJournalEntryReceived(_, _)) @@ -227,7 +280,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/3, 1); @@ -251,8 +304,8 @@ std::move(journal_mutation), base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->GetCallback(true); - storage_db()->UpdateCallback(true); + GetCallback(storage_db(), true); + UpdateCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/4, 1); @@ -270,7 +323,7 @@ kJournalKey2, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); @@ -290,7 +343,7 @@ kJournalKey3, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 2); @@ -310,7 +363,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 3); } @@ -332,7 +385,7 @@ base::BindOnce(&FeedJournalDatabaseTest::OnStorageCommitted, base::Unretained(this))); RunUntilIdle(); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaCommitMutationSizeHistogramName, /*operations=*/1, 1); @@ -348,7 +401,7 @@ kJournalKey2, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); @@ -367,7 +420,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 2); } @@ -388,7 +441,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -403,7 +456,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived, base::Unretained(this))); - storage_db()->GetCallback(true); + GetCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -428,7 +481,7 @@ db()->LoadAllJournalKeys( base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->LoadKeysCallback(true); + LoadKeysCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaSizeHistogramName, /*size=*/3, 1); @@ -449,7 +502,7 @@ EXPECT_CALL(*this, OnStorageCommitted(true)); db()->DeleteAllJournals(base::BindOnce( &FeedJournalDatabaseTest::OnStorageCommitted, base::Unretained(this))); - storage_db()->UpdateCallback(true); + UpdateCallback(storage_db(), true); histogram().ExpectTotalCount(kUmaOperationCommitTimeHistogramName, 1); @@ -462,7 +515,7 @@ db()->LoadAllJournalKeys( base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->LoadKeysCallback(true); + LoadKeysCallback(storage_db(), true); histogram().ExpectBucketCount(kUmaSizeHistogramName, /*size=*/0, 1); @@ -487,7 +540,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(false); + GetCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -505,7 +558,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->GetCallback(false); + GetCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -526,7 +579,7 @@ db()->LoadAllJournalKeys( base::BindOnce(&FeedJournalDatabaseTest::OnJournalEntryReceived, base::Unretained(this))); - storage_db()->LoadKeysCallback(false); + LoadKeysCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaSizeHistogramName, 0); histogram().ExpectTotalCount(kUmaLoadKeysTimeHistogramName, 1); @@ -548,7 +601,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived, base::Unretained(this))); - storage_db()->GetCallback(false); + GetCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); } @@ -563,7 +616,7 @@ kJournalKey1, base::BindOnce(&FeedJournalDatabaseTest::OnCheckJournalExistReceived, base::Unretained(this))); - storage_db()->GetCallback(false); + GetCallback(storage_db(), false); histogram().ExpectTotalCount(kUmaLoadTimeHistogramName, 1); }
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css index 98d2eeb..30c7851c 100644 --- a/components/flags_ui/resources/flags.css +++ b/components/flags_ui/resources/flags.css
@@ -229,6 +229,12 @@ text-transform: uppercase; } +.screen-reader-only { + display: inline-block; + position: fixed; + clip: rect(0px,0px,0px,0px); +} + #promos { color: var(--secondary-color); font-size: .875rem;
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index 4777e01..d49d2c7 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -36,6 +36,8 @@ <button id="experiment-reset-all" type="button" tabindex="3"> Reset all to default </button> + <div class="screen-reader-only" id="reset-all-success-message" + role="status">Reset complete</div> </div> </div> </div>
diff --git a/components/flags_ui/resources/flags.js b/components/flags_ui/resources/flags.js index e44879f..7c7b1815 100644 --- a/components/flags_ui/resources/flags.js +++ b/components/flags_ui/resources/flags.js
@@ -143,6 +143,8 @@ /** Reset all flags to their default values and refresh the UI. */ function resetAllFlags() { chrome.send('resetAllFlags'); + // Updating the message in order for it to get announced by screen readers. + $('reset-all-success-message').innerHTML += "!"; showRestartToast(true); requestExperimentalFeaturesData(); }
diff --git a/components/media_message_center/media_notification_controller.h b/components/media_message_center/media_notification_controller.h index ae1ed4f1..3e6a629 100644 --- a/components/media_message_center/media_notification_controller.h +++ b/components/media_message_center/media_notification_controller.h
@@ -9,6 +9,13 @@ #include "base/component_export.h" +template <typename T> +class scoped_refptr; + +namespace base { +class SequencedTaskRunner; +} // namespace base + namespace media_message_center { // MediaNotificationController does the actual hiding and showing of the media @@ -19,6 +26,14 @@ // MediaNotificationItem when the notification should be shown/hidden. virtual void ShowNotification(const std::string& id) = 0; virtual void HideNotification(const std::string& id) = 0; + + // Removes a notification item with the given request id. Called by + // MediaNotificationItem when it should be destroyed. + virtual void RemoveItem(const std::string& id) = 0; + + // Returns a task runner that the MediaNotificationItem should use. + // It typically returns null except in tests. + virtual scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const = 0; }; } // namespace media_message_center
diff --git a/components/media_message_center/media_notification_item.cc b/components/media_message_center/media_notification_item.cc index 00cd289..cb9a103 100644 --- a/components/media_message_center/media_notification_item.cc +++ b/components/media_message_center/media_notification_item.cc
@@ -36,6 +36,10 @@ return MediaNotificationItem::Source::kUnknown; } +// How long to wait (in milliseconds) for a new media session to begin. +constexpr base::TimeDelta kFreezeTimerDelay = + base::TimeDelta::FromMilliseconds(2500); + } // namespace // static @@ -54,11 +58,154 @@ media_session::mojom::MediaSessionInfoPtr session_info) : controller_(notification_controller), request_id_(request_id), - source_(GetSource(source_name)), - media_controller_ptr_(std::move(controller)), - session_info_(std::move(session_info)) { + source_(GetSource(source_name)) { DCHECK(controller_); + if (auto task_runner = notification_controller->GetTaskRunner()) + freeze_timer_.SetTaskRunner(task_runner); + + SetController(std::move(controller), std::move(session_info)); +} + +MediaNotificationItem::~MediaNotificationItem() { + controller_->HideNotification(request_id_); +} + +void MediaNotificationItem::MediaSessionInfoChanged( + media_session::mojom::MediaSessionInfoPtr session_info) { + session_info_ = std::move(session_info); + + MaybeUnfreeze(); + MaybeHideOrShowNotification(); + + if (view_ && !frozen_) + view_->UpdateWithMediaSessionInfo(session_info_); +} + +void MediaNotificationItem::MediaSessionMetadataChanged( + const base::Optional<media_session::MediaMetadata>& metadata) { + session_metadata_ = metadata.value_or(media_session::MediaMetadata()); + + view_needs_metadata_update_ = true; + + MaybeUnfreeze(); + MaybeHideOrShowNotification(); + + // |MaybeHideOrShowNotification()| can synchronously create a + // MediaNotificationView that calls |SetView()|. If that happens, then we + // don't want to call |view_->UpdateWithMediaMetadata()| below since |view_| + // will have already received the metadata when calling |SetView()|. + // |view_needs_metadata_update_| is set to false in |SetView()|. + if (view_ && view_needs_metadata_update_ && !frozen_) + view_->UpdateWithMediaMetadata(session_metadata_); + + view_needs_metadata_update_ = false; +} + +void MediaNotificationItem::MediaSessionActionsChanged( + const std::vector<media_session::mojom::MediaSessionAction>& actions) { + session_actions_ = std::set<media_session::mojom::MediaSessionAction>( + actions.begin(), actions.end()); + + if (view_ && !frozen_) { + DCHECK(view_); + view_->UpdateWithMediaActions(session_actions_); + } +} + +void MediaNotificationItem::MediaControllerImageChanged( + media_session::mojom::MediaSessionImageType type, + const SkBitmap& bitmap) { + DCHECK_EQ(media_session::mojom::MediaSessionImageType::kArtwork, type); + + session_artwork_ = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); + + if (view_ && !frozen_) + view_->UpdateWithMediaArtwork(*session_artwork_); +} + +void MediaNotificationItem::SetView(MediaNotificationView* view) { + DCHECK(view_ || view); + + view_ = view; + + if (view_) { + view_needs_metadata_update_ = false; + view_->UpdateWithMediaSessionInfo(session_info_); + view_->UpdateWithMediaMetadata(session_metadata_); + view_->UpdateWithMediaActions(session_actions_); + + if (session_artwork_.has_value()) + view_->UpdateWithMediaArtwork(*session_artwork_); + } +} + +void MediaNotificationItem::FlushForTesting() { + media_controller_ptr_.FlushForTesting(); +} + +bool MediaNotificationItem::ShouldShowNotification() const { + // If the |is_controllable| bit is set in MediaSessionInfo then we should show + // a media notification. + if (!session_info_ || !session_info_->is_controllable) + return false; + + // If we do not have a title and an artist then we should hide the + // notification. + if (session_metadata_.title.empty() || session_metadata_.artist.empty()) + return false; + + return true; +} + +void MediaNotificationItem::OnFreezeTimerFired() { + DCHECK(frozen_); + + if (is_bound_) { + controller_->HideNotification(request_id_); + } else { + controller_->RemoveItem(request_id_); + } +} + +void MediaNotificationItem::MaybeHideOrShowNotification() { + if (frozen_) + return; + + if (!ShouldShowNotification()) { + controller_->HideNotification(request_id_); + return; + } + + // If we have an existing view, then we don't need to create a new one. + if (view_) + return; + + controller_->ShowNotification(request_id_); + + UMA_HISTOGRAM_ENUMERATION(kSourceHistogramName, source_); +} + +void MediaNotificationItem::OnMediaSessionActionButtonPressed( + MediaSessionAction action) { + UMA_HISTOGRAM_ENUMERATION(kUserActionHistogramName, action); + + if (frozen_) + return; + + media_session::PerformMediaSessionAction(action, media_controller_ptr_); +} + +void MediaNotificationItem::SetController( + media_session::mojom::MediaControllerPtr controller, + media_session::mojom::MediaSessionInfoPtr session_info) { + observer_receiver_.reset(); + artwork_observer_receiver_.reset(); + + is_bound_ = true; + media_controller_ptr_ = std::move(controller); + session_info_ = std::move(session_info); + if (media_controller_ptr_.is_bound()) { // Bind an observer to the associated media controller. media_controller_ptr_->AddObserver( @@ -76,108 +223,27 @@ MaybeHideOrShowNotification(); } -MediaNotificationItem::~MediaNotificationItem() { - controller_->HideNotification(request_id_); -} - -void MediaNotificationItem::MediaSessionInfoChanged( - media_session::mojom::MediaSessionInfoPtr session_info) { - session_info_ = std::move(session_info); - - MaybeHideOrShowNotification(); - - if (view_) - view_->UpdateWithMediaSessionInfo(session_info_); -} - -void MediaNotificationItem::MediaSessionMetadataChanged( - const base::Optional<media_session::MediaMetadata>& metadata) { - session_metadata_ = metadata.value_or(media_session::MediaMetadata()); - - view_needs_metadata_update_ = true; - - MaybeHideOrShowNotification(); - - // |MaybeHideOrShowNotification()| can synchronously create a - // MediaNotificationView that calls |SetView()|. If that happens, then we - // don't want to call |view_->UpdateWithMediaMetadata()| below since |view_| - // will have already received the metadata when calling |SetView()|. - // |view_needs_metadata_update_| is set to false in |SetView()|. - if (view_ && view_needs_metadata_update_) - view_->UpdateWithMediaMetadata(session_metadata_); - - view_needs_metadata_update_ = false; -} - -void MediaNotificationItem::MediaSessionActionsChanged( - const std::vector<media_session::mojom::MediaSessionAction>& actions) { - session_actions_ = std::set<media_session::mojom::MediaSessionAction>( - actions.begin(), actions.end()); - - if (view_) - view_->UpdateWithMediaActions(session_actions_); -} - -void MediaNotificationItem::MediaControllerImageChanged( - media_session::mojom::MediaSessionImageType type, - const SkBitmap& bitmap) { - DCHECK_EQ(media_session::mojom::MediaSessionImageType::kArtwork, type); - - session_artwork_ = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); - - if (view_) - view_->UpdateWithMediaArtwork(*session_artwork_); -} - -void MediaNotificationItem::SetView(MediaNotificationView* view) { - DCHECK(view_ || view); - - view_ = view; - - if (view) { - view_needs_metadata_update_ = false; - view_->UpdateWithMediaSessionInfo(session_info_); - view_->UpdateWithMediaMetadata(session_metadata_); - view_->UpdateWithMediaActions(session_actions_); - - if (session_artwork_.has_value()) - view_->UpdateWithMediaArtwork(*session_artwork_); - } -} - -void MediaNotificationItem::FlushForTesting() { - media_controller_ptr_.FlushForTesting(); -} - -void MediaNotificationItem::MaybeHideOrShowNotification() { - // If the |is_controllable| bit is set in MediaSessionInfo then we should show - // a media notification. - if (!session_info_ || !session_info_->is_controllable) { - controller_->HideNotification(request_id_); - return; - } - - // If we do not have a title and an artist then we should hide the - // notification. - if (session_metadata_.title.empty() || session_metadata_.artist.empty()) { - controller_->HideNotification(request_id_); - return; - } - - // If we have an existing view, then we don't need to create a new one. - if (view_) +void MediaNotificationItem::Freeze() { + if (frozen_) return; - controller_->ShowNotification(request_id_); + frozen_ = true; + is_bound_ = false; - UMA_HISTOGRAM_ENUMERATION(kSourceHistogramName, source_); + freeze_timer_.Start(FROM_HERE, kFreezeTimerDelay, + base::BindOnce(&MediaNotificationItem::OnFreezeTimerFired, + base::Unretained(this))); } -void MediaNotificationItem::OnMediaSessionActionButtonPressed( - MediaSessionAction action) { - UMA_HISTOGRAM_ENUMERATION(kUserActionHistogramName, action); +void MediaNotificationItem::MaybeUnfreeze() { + if (!frozen_) + return; - media_session::PerformMediaSessionAction(action, media_controller_ptr_); + if (!ShouldShowNotification() || !is_bound_) + return; + + frozen_ = false; + freeze_timer_.Stop(); } } // namespace media_message_center
diff --git a/components/media_message_center/media_notification_item.h b/components/media_message_center/media_notification_item.h index 08f817e6..08a3465 100644 --- a/components/media_message_center/media_notification_item.h +++ b/components/media_message_center/media_notification_item.h
@@ -87,13 +87,30 @@ media_controller_ptr_ = std::move(controller); } + void SetController(media_session::mojom::MediaControllerPtr controller, + media_session::mojom::MediaSessionInfoPtr session_info); + + // This will freeze the item and start a timer to destroy the item after + // some time has passed. + void Freeze(); + + bool frozen() const { return frozen_; } + private: + bool ShouldShowNotification() const; + + void MaybeUnfreeze(); + + void OnFreezeTimerFired(); + void MaybeHideOrShowNotification(); void HideNotification(); MediaNotificationController* controller_; + bool is_bound_ = true; + // Weak reference to the view of the currently shown media notification. MediaNotificationView* view_ = nullptr; @@ -118,6 +135,14 @@ // updating |view_|'s metadata twice on a single change. bool view_needs_metadata_update_ = false; + // When the item is frozen the |view_| will not receive any updates to the + // data and no actions will be executed. + bool frozen_ = false; + + // The timer that will notify the controller to destroy this item after it + // has been frozen for a certain period of time. + base::OneShotTimer freeze_timer_; + mojo::Receiver<media_session::mojom::MediaControllerObserver> observer_receiver_{this};
diff --git a/components/media_message_center/media_notification_view_unittest.cc b/components/media_message_center/media_notification_view_unittest.cc index e213c732..c4aa88c 100644 --- a/components/media_message_center/media_notification_view_unittest.cc +++ b/components/media_message_center/media_notification_view_unittest.cc
@@ -67,6 +67,10 @@ // MediaNotificationController implementation. MOCK_METHOD1(ShowNotification, void(const std::string& id)); MOCK_METHOD1(HideNotification, void(const std::string& id)); + MOCK_METHOD1(RemoveItem, void(const std::string& id)); + scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override { + return nullptr; + } private: DISALLOW_COPY_AND_ASSIGN(MockMediaNotificationController); @@ -870,4 +874,72 @@ EXPECT_EQ(base::ASCIIToUTF16("title - artist"), accessible_name()); } +TEST_F(MediaNotificationViewTest, Freezing_DoNotUpdateMetadata) { + media_session::MediaMetadata metadata; + metadata.title = base::ASCIIToUTF16("title2"); + metadata.artist = base::ASCIIToUTF16("artist2"); + metadata.album = base::ASCIIToUTF16("album"); + + GetItem()->Freeze(); + GetItem()->MediaSessionMetadataChanged(metadata); + + EXPECT_EQ(base::ASCIIToUTF16("title"), title_label()->GetText()); + EXPECT_EQ(base::ASCIIToUTF16("artist"), artist_label()->GetText()); +} + +TEST_F(MediaNotificationViewTest, Freezing_DoNotUpdateImage) { + SkBitmap image; + image.allocN32Pixels(10, 10); + image.eraseColor(SK_ColorMAGENTA); + + GetItem()->Freeze(); + GetItem()->MediaControllerImageChanged( + media_session::mojom::MediaSessionImageType::kArtwork, image); + + EXPECT_TRUE(GetArtworkImage().isNull()); +} + +TEST_F(MediaNotificationViewTest, Freezing_DoNotUpdatePlaybackState) { + EnableAction(MediaSessionAction::kPlay); + EnableAction(MediaSessionAction::kPause); + + GetItem()->Freeze(); + + EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay)); + EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause)); + + media_session::mojom::MediaSessionInfoPtr session_info( + media_session::mojom::MediaSessionInfo::New()); + session_info->playback_state = + media_session::mojom::MediaPlaybackState::kPlaying; + GetItem()->MediaSessionInfoChanged(session_info.Clone()); + + EXPECT_TRUE(GetButtonForAction(MediaSessionAction::kPlay)); + EXPECT_FALSE(GetButtonForAction(MediaSessionAction::kPause)); +} + +TEST_F(MediaNotificationViewTest, Freezing_DoNotUpdateActions) { + EXPECT_FALSE( + GetButtonForAction(MediaSessionAction::kSeekForward)->GetVisible()); + + GetItem()->Freeze(); + EnableAction(MediaSessionAction::kSeekForward); + + EXPECT_FALSE( + GetButtonForAction(MediaSessionAction::kSeekForward)->GetVisible()); +} + +TEST_F(MediaNotificationViewTest, Freezing_DisableInteraction) { + EnableAllActions(); + + EXPECT_EQ(0, media_controller()->next_track_count()); + + GetItem()->Freeze(); + + SimulateButtonClick(MediaSessionAction::kNextTrack); + GetItem()->FlushForTesting(); + + EXPECT_EQ(0, media_controller()->next_track_count()); +} + } // namespace media_message_center
diff --git a/components/nacl/browser/nacl_browser_delegate.h b/components/nacl/browser/nacl_browser_delegate.h index 9d73cf0..d8abebb 100644 --- a/components/nacl/browser/nacl_browser_delegate.h +++ b/components/nacl/browser/nacl_browser_delegate.h
@@ -23,7 +23,8 @@ } // Encapsulates the dependencies of NaCl code on chrome/, to avoid a direct -// dependency on chrome/. +// dependency on chrome/. All methods should be called on the IO thread unless +// otherwise noted. class NaClBrowserDelegate { public: virtual ~NaClBrowserDelegate() {} @@ -63,17 +64,20 @@ // |use_blocking_api| to true, so calling blocking file API is allowed // otherwise non blocking API will be used (which only handles a subset of the // urls checking only the url scheme against kExtensionScheme). - virtual bool MapUrlToLocalFilePath(const GURL& url, - bool use_blocking_api, - const base::FilePath& profile_directory, - base::FilePath* file_path) = 0; + using MapUrlToLocalFilePathCallback = base::RepeatingCallback< + bool(const GURL& url, bool use_blocking_api, base::FilePath* file_path)>; + // Returns a MapUrlToLocalFilePathCallback that can be called on any thread. + // Must be called on the UI thread. + virtual MapUrlToLocalFilePathCallback GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) = 0; // Set match patterns which will be checked before enabling debug stub. virtual void SetDebugPatterns(const std::string& debug_patterns) = 0; // Returns whether NaCl application with this manifest URL should be debugged. virtual bool URLMatchesDebugPatterns(const GURL& manifest_url) = 0; - // Returns whether Non-SFI mode is allowed for a given manifest URL. + // Returns whether Non-SFI mode is allowed for a given manifest URL. Must be + // called on the UI thread. virtual bool IsNonSfiModeAllowed(const base::FilePath& profile_directory, const GURL& manifest_url) = 0; };
diff --git a/components/nacl/browser/nacl_file_host.cc b/components/nacl/browser/nacl_file_host.cc index c76d5a9..ff813f5e 100644 --- a/components/nacl/browser/nacl_file_host.cc +++ b/components/nacl/browser/nacl_file_host.cc
@@ -126,13 +126,11 @@ scoped_refptr<nacl::NaClHostMessageFilter> nacl_host_message_filter, const GURL& file_url, bool enable_validation_caching, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback, IPC::Message* reply_msg) { base::FilePath file_path; - if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( - file_url, - true /* use_blocking_api */, - nacl_host_message_filter->profile_directory(), - &file_path)) { + if (!map_url_callback.Run(file_url, true /* use_blocking_api */, + &file_path)) { NotifyRendererOfError(nacl_host_message_filter.get(), reply_msg); return; } @@ -248,13 +246,18 @@ return; } + auto map_url_callback = + nacl::NaClBrowser::GetDelegate()->GetMapUrlToLocalFilePathCallback( + nacl_host_message_filter->profile_directory()); + // The URL is part of the current app. Now query the extension system for the // file path and convert that to a file descriptor. This should be done on a // blocking pool thread. - base::PostTask(FROM_HERE, {base::ThreadPool(), base::MayBlock()}, - base::BindOnce(&DoOpenNaClExecutableOnThreadPool, - nacl_host_message_filter, file_url, - enable_validation_caching, reply_msg)); + base::PostTask( + FROM_HERE, {base::ThreadPool(), base::MayBlock()}, + base::BindOnce(&DoOpenNaClExecutableOnThreadPool, + nacl_host_message_filter, file_url, + enable_validation_caching, map_url_callback, reply_msg)); } } // namespace nacl_file_host
diff --git a/components/nacl/browser/nacl_host_message_filter.cc b/components/nacl/browser/nacl_host_message_filter.cc index fd6f887..9b8823a 100644 --- a/components/nacl/browser/nacl_host_message_filter.cc +++ b/components/nacl/browser/nacl_host_message_filter.cc
@@ -91,6 +91,15 @@ pnacl::PnaclHost::GetInstance()->RendererClosing(render_process_id_); } +void NaClHostMessageFilter::OverrideThreadForMessage( + const IPC::Message& message, + content::BrowserThread::ID* thread) { +#if BUILDFLAG(ENABLE_NACL) + if (message.type() == NaClHostMsg_LaunchNaCl::ID) + *thread = content::BrowserThread::UI; +#endif +} + bool NaClHostMessageFilter::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(NaClHostMessageFilter, message) @@ -122,26 +131,42 @@ void NaClHostMessageFilter::OnLaunchNaCl( const nacl::NaClLaunchParams& launch_params, IPC::Message* reply_msg) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + bool nonsfi_mode_allowed = false; +#if defined(OS_CHROMEOS) && \ + (defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARMEL)) + nonsfi_mode_allowed = NaClBrowser::GetDelegate()->IsNonSfiModeAllowed( + profile_directory_, GURL(launch_params.manifest_url)); +#endif + + auto map_url_callback = + nacl::NaClBrowser::GetDelegate()->GetMapUrlToLocalFilePathCallback( + profile_directory_); + // If we're running llc or ld for the PNaCl translator, we don't need to look // up permissions, and we don't have the right browser state to look up some // of the whitelisting parameters anyway. if (launch_params.process_type == kPNaClTranslatorProcessType) { uint32_t perms = launch_params.permission_bits & ppapi::PERMISSION_DEV; - LaunchNaClContinuationOnIOThread( - launch_params, - reply_msg, - std::vector<NaClResourcePrefetchResult>(), - ppapi::PpapiPermissions(perms)); + base::PostTask( + FROM_HERE, {content::BrowserThread::IO}, + base::BindOnce(&NaClHostMessageFilter::LaunchNaClContinuationOnIOThread, + this, launch_params, reply_msg, + std::vector<NaClResourcePrefetchResult>(), + ppapi::PpapiPermissions(perms), nonsfi_mode_allowed, + map_url_callback)); return; } - base::PostTask(FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&NaClHostMessageFilter::LaunchNaClContinuation, - this, launch_params, reply_msg)); + LaunchNaClContinuation(launch_params, reply_msg, nonsfi_mode_allowed, + map_url_callback); } void NaClHostMessageFilter::LaunchNaClContinuation( const nacl::NaClLaunchParams& launch_params, - IPC::Message* reply_msg) { + IPC::Message* reply_msg, + bool nonsfi_mode_allowed, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ppapi::PpapiPermissions permissions = @@ -185,24 +210,25 @@ {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_BLOCKING, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce(&NaClHostMessageFilter::BatchOpenResourceFiles, this, - safe_launch_params, reply_msg, permissions)); + safe_launch_params, reply_msg, permissions, + nonsfi_mode_allowed, map_url_callback)); } void NaClHostMessageFilter::BatchOpenResourceFiles( const nacl::NaClLaunchParams& launch_params, IPC::Message* reply_msg, - ppapi::PpapiPermissions permissions) { + ppapi::PpapiPermissions permissions, + bool nonsfi_mode_allowed, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback) { std::vector<NaClResourcePrefetchResult> prefetched_resource_files; const std::vector<NaClResourcePrefetchRequest>& request_list = launch_params.resource_prefetch_request_list; for (size_t i = 0; i < request_list.size(); ++i) { GURL gurl(request_list[i].resource_url); base::FilePath file_path_metadata; - if (!nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( - gurl, - true, // use_blocking_api - profile_directory_, - &file_path_metadata)) { + if (!map_url_callback.Run(gurl, + true, // use_blocking_api + &file_path_metadata)) { continue; } base::File file = nacl::OpenNaClReadExecImpl( @@ -222,14 +248,16 @@ FROM_HERE, {content::BrowserThread::IO}, base::BindOnce(&NaClHostMessageFilter::LaunchNaClContinuationOnIOThread, this, launch_params, reply_msg, prefetched_resource_files, - permissions)); + permissions, nonsfi_mode_allowed, map_url_callback)); } void NaClHostMessageFilter::LaunchNaClContinuationOnIOThread( const nacl::NaClLaunchParams& launch_params, IPC::Message* reply_msg, const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, - ppapi::PpapiPermissions permissions) { + ppapi::PpapiPermissions permissions, + bool nonsfi_mode_allowed, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); NaClFileToken nexe_token = { @@ -241,27 +269,18 @@ IPC::PlatformFileForTransitToPlatformFile(launch_params.nexe_file); NaClProcessHost* host = new NaClProcessHost( - GURL(launch_params.manifest_url), - base::File(nexe_file), - nexe_token, - prefetched_resource_files, - permissions, - launch_params.render_view_id, - launch_params.permission_bits, - launch_params.uses_nonsfi_mode, - off_the_record_, - launch_params.process_type, + GURL(launch_params.manifest_url), base::File(nexe_file), nexe_token, + prefetched_resource_files, permissions, launch_params.render_view_id, + launch_params.permission_bits, launch_params.uses_nonsfi_mode, + nonsfi_mode_allowed, off_the_record_, launch_params.process_type, profile_directory_); GURL manifest_url(launch_params.manifest_url); base::FilePath manifest_path; // We're calling MapUrlToLocalFilePath with the non-blocking API // because we're running in the I/O thread. Ideally we'd use the other path, // which would cover more cases. - nacl::NaClBrowser::GetDelegate()->MapUrlToLocalFilePath( - manifest_url, - false /* use_blocking_api */, - profile_directory_, - &manifest_path); + map_url_callback.Run(manifest_url, false /* use_blocking_api */, + &manifest_path); host->Launch(this, reply_msg, manifest_path); }
diff --git a/components/nacl/browser/nacl_host_message_filter.h b/components/nacl/browser/nacl_host_message_filter.h index 474ac45..84d29717 100644 --- a/components/nacl/browser/nacl_host_message_filter.h +++ b/components/nacl/browser/nacl_host_message_filter.h
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/nacl/browser/nacl_browser_delegate.h" #include "content/public/browser/browser_message_filter.h" #include "ppapi/shared_impl/ppapi_permissions.h" @@ -35,6 +36,8 @@ // content::BrowserMessageFilter methods: bool OnMessageReceived(const IPC::Message& message) override; void OnChannelClosing() override; + void OverrideThreadForMessage(const IPC::Message& message, + content::BrowserThread::ID* thread) override; int render_process_id() { return render_process_id_; } bool off_the_record() { return off_the_record_; } @@ -48,17 +51,24 @@ void OnLaunchNaCl(const NaClLaunchParams& launch_params, IPC::Message* reply_msg); - void BatchOpenResourceFiles(const nacl::NaClLaunchParams& launch_params, - IPC::Message* reply_msg, - ppapi::PpapiPermissions permissions); + void BatchOpenResourceFiles( + const nacl::NaClLaunchParams& launch_params, + IPC::Message* reply_msg, + ppapi::PpapiPermissions permissions, + bool nonsfi_mode_allowed, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback); void LaunchNaClContinuation( const nacl::NaClLaunchParams& launch_params, - IPC::Message* reply_msg); + IPC::Message* reply_msg, + bool nonsfi_mode_allowed, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback); void LaunchNaClContinuationOnIOThread( const nacl::NaClLaunchParams& launch_params, IPC::Message* reply_msg, const std::vector<NaClResourcePrefetchResult>& prefetched_resource_files, - ppapi::PpapiPermissions permissions); + ppapi::PpapiPermissions permissions, + bool nonsfi_mode_allowed, + NaClBrowserDelegate::MapUrlToLocalFilePathCallback map_url_callback); void OnGetReadonlyPnaclFd(const std::string& filename, bool is_executable, IPC::Message* reply_msg);
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index 3a124c5..66602a6e0 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -208,6 +208,7 @@ int render_view_id, uint32_t permission_bits, bool uses_nonsfi_mode, + bool nonsfi_mode_allowed, bool off_the_record, NaClAppProcessType process_type, const base::FilePath& profile_directory) @@ -224,6 +225,7 @@ debug_exception_handler_requested_(false), #endif uses_nonsfi_mode_(uses_nonsfi_mode), + nonsfi_mode_allowed_(nonsfi_mode_allowed), enable_debug_stub_(false), enable_crash_throttling_(false), off_the_record_(off_the_record), @@ -378,18 +380,12 @@ if (uses_nonsfi_mode_) { bool nonsfi_mode_forced_by_command_line = false; - bool nonsfi_mode_allowed = false; #if defined(OS_LINUX) nonsfi_mode_forced_by_command_line = cmd->HasSwitch(switches::kEnableNaClNonSfiMode); -#if defined(OS_CHROMEOS) && \ - (defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARMEL)) - nonsfi_mode_allowed = NaClBrowser::GetDelegate()->IsNonSfiModeAllowed( - nacl_host_message_filter->profile_directory(), manifest_url_); -#endif #endif bool nonsfi_mode_enabled = - nonsfi_mode_forced_by_command_line || nonsfi_mode_allowed; + nonsfi_mode_forced_by_command_line || nonsfi_mode_allowed_; if (!nonsfi_mode_enabled) { SendErrorToRenderer(
diff --git a/components/nacl/browser/nacl_process_host.h b/components/nacl/browser/nacl_process_host.h index 82d72ec..6db9dfc 100644 --- a/components/nacl/browser/nacl_process_host.h +++ b/components/nacl/browser/nacl_process_host.h
@@ -81,6 +81,7 @@ int render_view_id, uint32_t permission_bits, bool uses_nonsfi_mode, + bool nonsfi_mode_allowed, bool off_the_record, NaClAppProcessType process_type, const base::FilePath& profile_directory); @@ -230,6 +231,7 @@ std::unique_ptr<content::BrowserChildProcessHost> process_; bool uses_nonsfi_mode_; + bool nonsfi_mode_allowed_; bool enable_debug_stub_; bool enable_crash_throttling_;
diff --git a/components/nacl/browser/test_nacl_browser_delegate.cc b/components/nacl/browser/test_nacl_browser_delegate.cc index 81e925c1..7c07998 100644 --- a/components/nacl/browser/test_nacl_browser_delegate.cc +++ b/components/nacl/browser/test_nacl_browser_delegate.cc
@@ -41,12 +41,11 @@ return NULL; } -bool TestNaClBrowserDelegate::MapUrlToLocalFilePath( - const GURL& url, - bool use_blocking_api, - const base::FilePath& profile_directory, - base::FilePath* file_path) { - return false; +NaClBrowserDelegate::MapUrlToLocalFilePathCallback +TestNaClBrowserDelegate::GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) { + return base::BindRepeating([](const GURL& url, bool use_blocking_api, + base::FilePath* file_path) { return false; }); } void TestNaClBrowserDelegate::SetDebugPatterns(
diff --git a/components/nacl/browser/test_nacl_browser_delegate.h b/components/nacl/browser/test_nacl_browser_delegate.h index 69dde4e..5ee3d72e 100644 --- a/components/nacl/browser/test_nacl_browser_delegate.h +++ b/components/nacl/browser/test_nacl_browser_delegate.h
@@ -32,10 +32,8 @@ std::string GetVersionString() const override; ppapi::host::HostFactory* CreatePpapiHostFactory( content::BrowserPpapiHost* ppapi_host) override; - bool MapUrlToLocalFilePath(const GURL& url, - bool use_blocking_api, - const base::FilePath& profile_directory, - base::FilePath* file_path) override; + MapUrlToLocalFilePathCallback GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) override; void SetDebugPatterns(const std::string& debug_patterns) override; bool URLMatchesDebugPatterns(const GURL& manifest_url) override; bool IsNonSfiModeAllowed(const base::FilePath& profile_directory,
diff --git a/components/optimization_guide/BUILD.gn b/components/optimization_guide/BUILD.gn index a8b92a6d1..6e1e40a7 100644 --- a/components/optimization_guide/BUILD.gn +++ b/components/optimization_guide/BUILD.gn
@@ -21,8 +21,8 @@ "hints_fetcher.h", "hints_processing_util.cc", "hints_processing_util.h", - "host_filter.cc", - "host_filter.h", + "optimization_filter.cc", + "optimization_filter.h", "optimization_guide_constants.cc", "optimization_guide_constants.h", "optimization_guide_features.cc", @@ -80,7 +80,7 @@ "hints_component_util_unittest.cc", "hints_fetcher_unittest.cc", "hints_processing_util_unittest.cc", - "host_filter_unittest.cc", + "optimization_filter_unittest.cc", "optimization_guide_features_unittest.cc", "optimization_guide_service_unittest.cc", "optimization_guide_switches_unittest.cc",
diff --git a/components/optimization_guide/host_filter_unittest.cc b/components/optimization_guide/host_filter_unittest.cc deleted file mode 100644 index 8c49bd1c..0000000 --- a/components/optimization_guide/host_filter_unittest.cc +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/optimization_guide/host_filter.h" - -#include "base/macros.h" -#include "components/optimization_guide/bloom_filter.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace optimization_guide { - -namespace { - -std::unique_ptr<BloomFilter> CreateBloomFilter() { - std::unique_ptr<BloomFilter> filter = std::make_unique<BloomFilter>( - 7 /* num_hash_functions */, 8191 /* num_bits */); - return filter; -} - -TEST(HostFilterTest, TestContainsHostSuffix) { - std::unique_ptr<BloomFilter> bloom_filter(CreateBloomFilter()); - bloom_filter->Add("fooco.co.uk"); - HostFilter host_filter(std::move(bloom_filter)); - EXPECT_TRUE( - host_filter.ContainsHostSuffix(GURL("http://shopping.fooco.co.uk"))); - EXPECT_TRUE(host_filter.ContainsHostSuffix( - GURL("https://shopping.fooco.co.uk/somepath"))); - EXPECT_TRUE(host_filter.ContainsHostSuffix(GURL("https://fooco.co.uk"))); - EXPECT_FALSE(host_filter.ContainsHostSuffix(GURL("https://nonfooco.co.uk"))); -} - -TEST(HostFilterTest, TestContainsHostSuffixMaxSuffix) { - std::unique_ptr<BloomFilter> bloom_filter(CreateBloomFilter()); - bloom_filter->Add("one.two.three.four.co.uk"); - bloom_filter->Add("one.two.three.four.five.co.uk"); - HostFilter host_filter(std::move(bloom_filter)); - EXPECT_TRUE(host_filter.ContainsHostSuffix( - GURL("http://host.one.two.three.four.co.uk"))); - EXPECT_FALSE(host_filter.ContainsHostSuffix( - GURL("http://host.one.two.three.four.five.co.uk"))); - - // Note: full host will match even if more than 5 elements. - EXPECT_TRUE(host_filter.ContainsHostSuffix( - GURL("http://one.two.three.four.five.co.uk"))); -} - -TEST(HostFilterTest, TestContainsHostSuffixMinSuffix) { - std::unique_ptr<BloomFilter> bloom_filter(CreateBloomFilter()); - bloom_filter->Add("abc.tv"); - bloom_filter->Add("xy.tv"); - HostFilter host_filter(std::move(bloom_filter)); - EXPECT_TRUE(host_filter.ContainsHostSuffix(GURL("https://abc.tv"))); - EXPECT_TRUE(host_filter.ContainsHostSuffix(GURL("https://host.abc.tv"))); - EXPECT_FALSE(host_filter.ContainsHostSuffix(GURL("https://host.xy.tv"))); - - // Note: full host will match even if less than min size. - EXPECT_TRUE(host_filter.ContainsHostSuffix(GURL("https://xy.tv"))); -} - -} // namespace - -} // namespace optimization_guide
diff --git a/components/optimization_guide/host_filter.cc b/components/optimization_guide/optimization_filter.cc similarity index 84% rename from components/optimization_guide/host_filter.cc rename to components/optimization_guide/optimization_filter.cc index 20636e7..701b5a3 100644 --- a/components/optimization_guide/host_filter.cc +++ b/components/optimization_guide/optimization_filter.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/optimization_guide/host_filter.h" - #include <string> +#include "components/optimization_guide/optimization_filter.h" + namespace optimization_guide { // Maximum number of suffixes to check per url. @@ -14,18 +14,19 @@ // Realistic minimum length of a host suffix. const int kMinHostSuffix = 6; // eg., abc.tv -HostFilter::HostFilter(std::unique_ptr<BloomFilter> bloom_filter) +OptimizationFilter::OptimizationFilter( + std::unique_ptr<BloomFilter> bloom_filter) : bloom_filter_(std::move(bloom_filter)) { // May be created on one thread but used on another. The first call to // CalledOnValidSequence() will re-bind it. DETACH_FROM_SEQUENCE(sequence_checker_); } -HostFilter::~HostFilter() { +OptimizationFilter::~OptimizationFilter() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } -bool HostFilter::ContainsHostSuffix(const GURL& url) const { +bool OptimizationFilter::ContainsHostSuffix(const GURL& url) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // First check full host name.
diff --git a/components/optimization_guide/host_filter.h b/components/optimization_guide/optimization_filter.h similarity index 66% rename from components/optimization_guide/host_filter.h rename to components/optimization_guide/optimization_filter.h index b74da202..aa0bd858 100644 --- a/components/optimization_guide/host_filter.h +++ b/components/optimization_guide/optimization_filter.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_OPTIMIZATION_GUIDE_HOST_FILTER_H_ -#define COMPONENTS_OPTIMIZATION_GUIDE_HOST_FILTER_H_ +#ifndef COMPONENTS_OPTIMIZATION_GUIDE_OPTIMIZATION_FILTER_H_ +#define COMPONENTS_OPTIMIZATION_GUIDE_OPTIMIZATION_FILTER_H_ #include "base/macros.h" #include "base/sequence_checker.h" @@ -12,16 +12,18 @@ namespace optimization_guide { -// HostFilter is a simple Host filter for keeping track of a set of strings -// that are represented by a Bloom filter. +// OptimizationFilter is a simple filter for keeping track of a set of strings +// that are represented by a Bloom filter. This class has a 1:1 mapping with an +// OptimizationFilter protobuf message where this is the logical implementation +// of the proto data. // // TODO(dougarnett): consider moving this and BloomFilter under // components/blacklist/. -class HostFilter { +class OptimizationFilter { public: - explicit HostFilter(std::unique_ptr<BloomFilter> bloom_filter); + explicit OptimizationFilter(std::unique_ptr<BloomFilter> bloom_filter); - virtual ~HostFilter(); + virtual ~OptimizationFilter(); // Returns whether this filter contains a host suffix for the host part // of |url|. It will check at most 5 host suffixes and it may ignore simple @@ -43,9 +45,9 @@ SEQUENCE_CHECKER(sequence_checker_); - DISALLOW_COPY_AND_ASSIGN(HostFilter); + DISALLOW_COPY_AND_ASSIGN(OptimizationFilter); }; } // namespace optimization_guide -#endif // COMPONENTS_OPTIMIZATION_GUIDE_HOST_FILTER_H_ +#endif // COMPONENTS_OPTIMIZATION_GUIDE_OPTIMIZATION_FILTER_H_
diff --git a/components/optimization_guide/optimization_filter_unittest.cc b/components/optimization_guide/optimization_filter_unittest.cc new file mode 100644 index 0000000..79a01442 --- /dev/null +++ b/components/optimization_guide/optimization_filter_unittest.cc
@@ -0,0 +1,63 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/optimization_guide/optimization_filter.h" +#include "base/macros.h" +#include "components/optimization_guide/bloom_filter.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace optimization_guide { + +namespace { + +std::unique_ptr<BloomFilter> CreateBloomFilter() { + std::unique_ptr<BloomFilter> filter = std::make_unique<BloomFilter>( + 7 /* num_hash_functions */, 8191 /* num_bits */); + return filter; +} + +TEST(OptimizationFilterTest, TestContainsHostSuffix) { + std::unique_ptr<BloomFilter> bloom_filter(CreateBloomFilter()); + bloom_filter->Add("fooco.co.uk"); + OptimizationFilter opt_filter(std::move(bloom_filter)); + EXPECT_TRUE( + opt_filter.ContainsHostSuffix(GURL("http://shopping.fooco.co.uk"))); + EXPECT_TRUE(opt_filter.ContainsHostSuffix( + GURL("https://shopping.fooco.co.uk/somepath"))); + EXPECT_TRUE(opt_filter.ContainsHostSuffix(GURL("https://fooco.co.uk"))); + EXPECT_FALSE(opt_filter.ContainsHostSuffix(GURL("https://nonfooco.co.uk"))); +} + +TEST(OptimizationFilterTest, TestContainsHostSuffixMaxSuffix) { + std::unique_ptr<BloomFilter> bloom_filter(CreateBloomFilter()); + bloom_filter->Add("one.two.three.four.co.uk"); + bloom_filter->Add("one.two.three.four.five.co.uk"); + OptimizationFilter opt_filter(std::move(bloom_filter)); + EXPECT_TRUE(opt_filter.ContainsHostSuffix( + GURL("http://host.one.two.three.four.co.uk"))); + EXPECT_FALSE(opt_filter.ContainsHostSuffix( + GURL("http://host.one.two.three.four.five.co.uk"))); + + // Note: full host will match even if more than 5 elements. + EXPECT_TRUE(opt_filter.ContainsHostSuffix( + GURL("http://one.two.three.four.five.co.uk"))); +} + +TEST(OptimizationFilterTest, TestContainsHostSuffixMinSuffix) { + std::unique_ptr<BloomFilter> bloom_filter(CreateBloomFilter()); + bloom_filter->Add("abc.tv"); + bloom_filter->Add("xy.tv"); + OptimizationFilter opt_filter(std::move(bloom_filter)); + EXPECT_TRUE(opt_filter.ContainsHostSuffix(GURL("https://abc.tv"))); + EXPECT_TRUE(opt_filter.ContainsHostSuffix(GURL("https://host.abc.tv"))); + EXPECT_FALSE(opt_filter.ContainsHostSuffix(GURL("https://host.xy.tv"))); + + // Note: full host will match even if less than min size. + EXPECT_TRUE(opt_filter.ContainsHostSuffix(GURL("https://xy.tv"))); +} + +} // namespace + +} // namespace optimization_guide
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp index 532169e3..528271f 100644 --- a/components/page_info_strings.grdp +++ b/components/page_info_strings.grdp
@@ -45,6 +45,9 @@ <message name="IDS_PAGE_INFO_SAFETY_TIP_LEAVE_BUTTON" desc="Text of button to leave a suspicious page shown on the safety tip page info bubble."> Leave this site </message> + <message name="IDS_PAGE_INFO_SAFETY_TIP_SUMMARY" desc="Message to display in the page info bubble when the page you are on triggered a safety tip."> + Suspicious site + </message> <!-- Viewing file strings --> <message name="IDS_PAGE_INFO_FILE_PAGE" desc="Message to display in the page info bubble when the page the user has navigated to is a file:// page">
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_SAFETY_TIP_SUMMARY.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_SAFETY_TIP_SUMMARY.png.sha1 new file mode 100644 index 0000000..f5f4107 --- /dev/null +++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_SAFETY_TIP_SUMMARY.png.sha1
@@ -0,0 +1 @@ +a529530d0ddcd81921d7f17316a5ddb453b3aef6 \ No newline at end of file
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index 3dc120a0..72ad166d 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -94,7 +94,7 @@ return; doc_info_ = doc_info; - doc_node_ = CreateNode(ax::mojom::Role::kGroup); + doc_node_ = CreateNode(ax::mojom::Role::kDocument); // Because all of the coordinates are expressed relative to the // doc's coordinates, the origin of the doc must be (0, 0). Its @@ -119,6 +119,8 @@ page_node->AddStringAttribute( ax::mojom::StringAttribute::kName, l10n_util::GetPluralStringFUTF8(IDS_PDF_PAGE_INDEX, page_index + 1)); + page_node->AddBoolAttribute(ax::mojom::BoolAttribute::kIsPageBreakingObject, + true); gfx::RectF page_bounds = ToRectF(page_info.bounds); page_node->relative_bounds.bounds = page_bounds; @@ -479,7 +481,7 @@ } bool PdfAccessibilityTree::IsIgnored(const ui::AXNode* node) const { - return node->data().HasState(ax::mojom::State::kIgnored); + return node->IsIgnored(); } bool PdfAccessibilityTree::IsValid(const ui::AXNode* node) const {
diff --git a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc index e262962..7cc80a7 100644 --- a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc +++ b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
@@ -131,7 +131,7 @@ pdf_accessibility_tree.SetAccessibilityPageInfo(page_info_, text_runs_, chars_); - EXPECT_EQ(ax::mojom::Role::kGroup, + EXPECT_EQ(ax::mojom::Role::kDocument, pdf_accessibility_tree.GetRoot()->data().role); }
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index cf05ae4..9c6648d 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -409,6 +409,7 @@ "//components/account_id", "//components/policy:generated", "//components/prefs:test_support", + "//components/version_info:version_info", "//extensions/buildflags", "//google_apis", "//net:test_support",
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 1460e6f..31d8df2a 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -555,7 +555,7 @@ request_jobs_.push_back(service_->CreateJob(std::move(config))); } -void CloudPolicyClient::UploadRealtimeReport(base::Value event, +void CloudPolicyClient::UploadRealtimeReport(base::Value report, const StatusCallback& callback) { CHECK(is_registered()); std::unique_ptr<RealtimeReportingJobConfiguration> config = @@ -565,7 +565,7 @@ &CloudPolicyClient::OnRealtimeReportUploadCompleted, weak_ptr_factory_.GetWeakPtr(), callback)); - config->AddEvent(std::move(event)); + config->AddReport(std::move(report)); request_jobs_.push_back(service_->CreateJob(std::move(config))); }
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h index ebefbc9..a77d9dfc 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.h +++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -262,10 +262,10 @@ chrome_desktop_report, const StatusCallback& callback); - // Uploads |event| using the real-time reporting API. As above, the client + // Uploads |report| using the real-time reporting API. As above, the client // must be in a registered state. The |callback| will be called when the // operation completes. - virtual void UploadRealtimeReport(base::Value event, + virtual void UploadRealtimeReport(base::Value report, const StatusCallback& callback); // Uploads a report on the status of app push-installs. The client must be in
diff --git a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc index 3b7fa0b7..7819492 100644 --- a/components/policy/core/common/cloud/cloud_policy_client_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_client_unittest.cc
@@ -14,6 +14,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/compiler_specific.h" +#include "base/json/json_reader.h" #include "base/memory/ref_counted.h" #include "base/run_loop.h" #include "base/stl_util.h" @@ -25,7 +26,9 @@ #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "components/policy/core/common/cloud/mock_device_management_service.h" #include "components/policy/core/common/cloud/mock_signing_service.h" +#include "components/policy/core/common/cloud/realtime_reporting_job_configuration.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "components/version_info/version_info.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" @@ -464,6 +467,7 @@ EXPECT_CALL(service_, StartJob(_)) .WillOnce(DoAll(service_.CaptureJobType(&job_type_), service_.CaptureQueryParams(&query_params_), + service_.CapturePayload(&job_payload_), service_.StartJobAsync( net::OK, DeviceManagementService::kSuccess, "{}"))); } @@ -586,6 +590,7 @@ DeviceManagementService::JobConfiguration::JobType job_type_; DeviceManagementService::JobConfiguration::ParameterMap query_params_; em::DeviceManagementRequest job_request_; + std::string job_payload_; std::string client_id_; std::string policy_type_; MockDeviceManagementService service_; @@ -1419,6 +1424,8 @@ EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); } +#if defined(OS_WIN) || defined(OS_MACOSX) || \ + defined(OS_LINUX) && !defined(OS_CHROMEOS) TEST_F(CloudPolicyClientTest, UploadRealtimeReport) { Register(); @@ -1427,18 +1434,47 @@ CloudPolicyClient::StatusCallback callback = base::Bind(&MockStatusCallbackObserver::OnCallbackComplete, base::Unretained(&callback_observer_)); - base::Value event(base::Value::Type::DICTIONARY); - event.SetStringKey("eventId", "123"); - event.SetStringKey("time", "2019-05-22T13:01:45Z"); - event.SetStringPath("event.foo", "bar"); + base::Value report(base::Value::Type::DICTIONARY); + report.SetStringPath("context.gaiaEmail", "name@gmail.com"); + report.SetStringPath("context.userAgent", "User-Agent"); + report.SetStringPath("context.profileName", "Profile 1"); + report.SetStringPath("context.profilePath", "C:\\User Data\\Profile 1"); + report.SetStringPath("event.time", "2019-05-22T13:01:45Z"); + report.SetStringPath("event.foo.prop1", "value1"); + report.SetStringPath("event.foo.prop2", "value2"); + report.SetStringPath("event.foo.prop3", "value3"); - client_->UploadRealtimeReport(std::move(event), callback); + client_->UploadRealtimeReport(std::move(report), callback); base::RunLoop().RunUntilIdle(); EXPECT_EQ( DeviceManagementService::JobConfiguration::TYPE_UPLOAD_REAL_TIME_REPORT, job_type_); EXPECT_EQ(DM_STATUS_SUCCESS, client_->status()); + + base::Optional<base::Value> payload = base::JSONReader::Read(job_payload_); + ASSERT_TRUE(payload); + + EXPECT_EQ(kDMToken, *payload->FindStringPath( + RealtimeReportingJobConfiguration::kDmTokenKey)); + EXPECT_EQ(client_id_, *payload->FindStringPath( + RealtimeReportingJobConfiguration::kClientIdKey)); + EXPECT_EQ(policy::GetOSUsername(), + *payload->FindStringPath( + RealtimeReportingJobConfiguration::kMachineUserKey)); + EXPECT_EQ(version_info::GetVersionNumber(), + *payload->FindStringPath( + RealtimeReportingJobConfiguration::kChromeVersionKey)); + EXPECT_EQ(policy::GetOSVersion(), + *payload->FindStringPath( + RealtimeReportingJobConfiguration::kOsVersionKey)); + + base::Value* events = + payload->FindPath(RealtimeReportingJobConfiguration::kEventsKey); + EXPECT_EQ(base::Value::Type::LIST, events->type()); + const base::Value::ListStorage& list = events->GetList(); + EXPECT_EQ(1u, list.size()); } +#endif TEST_F(CloudPolicyClientTest, MultipleActiveRequests) { Register();
diff --git a/components/policy/core/common/cloud/mock_device_management_service.cc b/components/policy/core/common/cloud/mock_device_management_service.cc index 8d82273..06f34bb 100644 --- a/components/policy/core/common/cloud/mock_device_management_service.cc +++ b/components/policy/core/common/cloud/mock_device_management_service.cc
@@ -76,6 +76,10 @@ CHECK(request->ParseFromString(payload)); } +ACTION_P(CreateCapturePayloadAction, payload) { + *payload = arg0->GetConfiguration()->GetPayload(); +} + MockDeviceManagementServiceConfiguration:: MockDeviceManagementServiceConfiguration() : server_url_(kServerUrl) {} @@ -180,6 +184,11 @@ return CreateCaptureRequestAction(request); } +testing::Action<MockDeviceManagementService::StartJobFunction> +MockDeviceManagementService::CapturePayload(std::string* payload) { + return CreateCapturePayloadAction(payload); +} + // Call after using StartJobFullControl() to respond to the network request. void MockDeviceManagementService::DoURLCompletion( JobControl** job,
diff --git a/components/policy/core/common/cloud/mock_device_management_service.h b/components/policy/core/common/cloud/mock_device_management_service.h index 0ff32159..37ee882 100644 --- a/components/policy/core/common/cloud/mock_device_management_service.h +++ b/components/policy/core/common/cloud/mock_device_management_service.h
@@ -111,6 +111,11 @@ testing::Action<StartJobFunction> CaptureRequest( enterprise_management::DeviceManagementRequest* request); + // Can be used as an action when mocking the StartJob method. + // Makes a copy of the payload of the JobConfiguration + // of the Job passed to StartJob. + testing::Action<StartJobFunction> CapturePayload(std::string* payload); + // Call after using StartJobFullControl() to respond to the network request. // If the job completed successfully, |*job| will be nulled to prevent callers // from using the pointer beyond its lifetime. If the job was retried, then
diff --git a/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc b/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc index 84455537..8de14966 100644 --- a/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc +++ b/components/policy/core/common/cloud/realtime_reporting_job_configuration.cc
@@ -1,4 +1,4 @@ -// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 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. @@ -6,8 +6,12 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "base/optional.h" +#include "base/path_service.h" #include "components/policy/core/common/cloud/cloud_policy_client.h" +#include "components/policy/core/common/cloud/cloud_policy_util.h" #include "components/policy/core/common/cloud/dm_auth.h" +#include "components/version_info/version_info.h" #include "google_apis/google_api_keys.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -15,9 +19,21 @@ namespace policy { -const char RealtimeReportingJobConfiguration::kDmTokenKey[] = "dmToken"; -const char RealtimeReportingJobConfiguration::kClientIdKey[] = "clientId"; +const char RealtimeReportingJobConfiguration::kContextKey[] = "context"; +const char RealtimeReportingJobConfiguration::kEventKey[] = "event"; + +const char RealtimeReportingJobConfiguration::kBrowserIdKey[] = + "browser.browserId"; +const char RealtimeReportingJobConfiguration::kChromeVersionKey[] = + "browser.chromeVersion"; +const char RealtimeReportingJobConfiguration::kClientIdKey[] = + "device.clientId"; +const char RealtimeReportingJobConfiguration::kDmTokenKey[] = "device.dmToken"; const char RealtimeReportingJobConfiguration::kEventsKey[] = "events"; +const char RealtimeReportingJobConfiguration::kMachineUserKey[] = + "browser.machineUser"; +const char RealtimeReportingJobConfiguration::kOsVersionKey[] = + "device.osVersion"; RealtimeReportingJobConfiguration::RealtimeReportingJobConfiguration( CloudPolicyClient* client, @@ -33,17 +49,46 @@ DCHECK(GetAuth().has_dm_token()); AddParameter("key", google_apis::GetAPIKey()); - - payload_.SetStringKey(kDmTokenKey, GetAuth().dm_token()); - payload_.SetStringKey(kClientIdKey, client->client_id()); - payload_.SetKey(kEventsKey, base::Value(base::Value::Type::LIST)); + InitializePayload(client); } RealtimeReportingJobConfiguration::~RealtimeReportingJobConfiguration() {} -void RealtimeReportingJobConfiguration::AddEvent(base::Value event) { +bool RealtimeReportingJobConfiguration::AddReport(base::Value report) { + if (!report.is_dict()) + return false; + + base::Optional<base::Value> context = report.ExtractKey(kContextKey); + base::Optional<base::Value> event = report.ExtractKey(kEventKey); + if (!context || !event) + return false; + + // Move context keys to the payload. It is possible to add multiple reports + // to the payload in which case the context values are the same. Only add + // any new values not already present. + for (const auto& item : context->DictItems()) { + if (!payload_.FindKey(item.first)) + payload_.SetKey(item.first, item.second.Clone()); + } + + // Append event to the list. base::Value::ListStorage& list = payload_.FindListKey(kEventsKey)->GetList(); - list.push_back(std::move(event)); + list.push_back(std::move(*event)); + return true; +} + +void RealtimeReportingJobConfiguration::InitializePayload( + CloudPolicyClient* client) { + base::FilePath browser_id; + if (base::PathService::Get(base::DIR_EXE, &browser_id)) + payload_.SetStringPath(kBrowserIdKey, browser_id.value()); + + payload_.SetStringPath(kDmTokenKey, GetAuth().dm_token()); + payload_.SetStringPath(kClientIdKey, client->client_id()); + payload_.SetStringPath(kMachineUserKey, GetOSUsername()); + payload_.SetStringPath(kChromeVersionKey, version_info::GetVersionNumber()); + payload_.SetStringPath(kOsVersionKey, GetOSVersion()); + payload_.SetPath(kEventsKey, base::Value(base::Value::Type::LIST)); } std::string RealtimeReportingJobConfiguration::GetPayload() {
diff --git a/components/policy/core/common/cloud/realtime_reporting_job_configuration.h b/components/policy/core/common/cloud/realtime_reporting_job_configuration.h index 68c0675f..26b06ad 100644 --- a/components/policy/core/common/cloud/realtime_reporting_job_configuration.h +++ b/components/policy/core/common/cloud/realtime_reporting_job_configuration.h
@@ -1,4 +1,4 @@ -// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -22,6 +22,19 @@ class POLICY_EXPORT RealtimeReportingJobConfiguration : public JobConfigurationBase { public: + // Keys used in report dictionary. + static const char kContextKey[]; + static const char kEventKey[]; + + // Keys used in request payload dictionary. Public for testing. + static const char kBrowserIdKey[]; + static const char kChromeVersionKey[]; + static const char kClientIdKey[]; + static const char kDmTokenKey[]; + static const char kEventsKey[]; + static const char kMachineUserKey[]; + static const char kOsVersionKey[]; + typedef base::OnceCallback<void(DeviceManagementService::Job* job, DeviceManagementStatus code, int net_error, @@ -34,16 +47,21 @@ ~RealtimeReportingJobConfiguration() override; - // Add a new event to the payload. This methods takes ownership of the event - // value. Events are dictionaries defined by the Event message described at + // Add a new report to the payload. A report is a dictionary that contains + // two keys: "event" and "context". The first key is a dictionary defined by + // the Event message described at // google/internal/chrome/reporting/v1/chromereporting.proto. - void AddEvent(base::Value event); + // + // The second is context information about this instance of chrome that + // is not specific to the event. + // + // Returns true if the report was added successfully. + bool AddReport(base::Value report); private: - // Keys used in request payload dictionary. - static const char kDmTokenKey[]; - static const char kClientIdKey[]; - static const char kEventsKey[]; + // Does one time initialization of the payload when the configuration is + // created. + void InitializePayload(CloudPolicyClient* client); // DeviceManagementService::JobConfiguration. std::string GetPayload() override;
diff --git a/components/previews/content/previews_hints.cc b/components/previews/content/previews_hints.cc index adfe31e..7ea0939e 100644 --- a/components/previews/content/previews_hints.cc +++ b/components/previews/content/previews_hints.cc
@@ -266,7 +266,7 @@ bloom_filter_proto.num_hash_functions(), bloom_filter_proto.num_bits(), bloom_filter_proto.data()); lite_page_redirect_blacklist_ = - std::make_unique<optimization_guide::HostFilter>( + std::make_unique<optimization_guide::OptimizationFilter>( std::move(bloom_filter)); RecordOptimizationFilterStatus( blacklist.optimization_type(),
diff --git a/components/previews/content/previews_hints.h b/components/previews/content/previews_hints.h index aa01f64a..fcf7bf8 100644 --- a/components/previews/content/previews_hints.h +++ b/components/previews/content/previews_hints.h
@@ -13,7 +13,7 @@ #include "base/sequence_checker.h" #include "components/optimization_guide/hint_cache.h" #include "components/optimization_guide/hints_processing_util.h" -#include "components/optimization_guide/host_filter.h" +#include "components/optimization_guide/optimization_filter.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/previews/content/previews_user_data.h" #include "net/nqe/effective_connection_type.h" @@ -114,7 +114,8 @@ std::unique_ptr<optimization_guide::HintUpdateData> component_update_data_; // Blacklist of host suffixes for LITE_PAGE_REDIRECT Previews. - std::unique_ptr<optimization_guide::HostFilter> lite_page_redirect_blacklist_; + std::unique_ptr<optimization_guide::OptimizationFilter> + lite_page_redirect_blacklist_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/components/previews/content/previews_hints_unittest.cc b/components/previews/content/previews_hints_unittest.cc index 06bce379..2c02021 100644 --- a/components/previews/content/previews_hints_unittest.cc +++ b/components/previews/content/previews_hints_unittest.cc
@@ -20,7 +20,6 @@ #include "components/optimization_guide/hint_update_data.h" #include "components/optimization_guide/hints_component_info.h" #include "components/optimization_guide/hints_component_util.h" -#include "components/optimization_guide/host_filter.h" #include "components/optimization_guide/optimization_guide_features.h" #include "components/optimization_guide/proto/hints.pb.h" #include "components/optimization_guide/proto_database_provider_test_base.h" @@ -61,19 +60,6 @@ } // namespace -class TestHostFilter : public optimization_guide::HostFilter { - public: - explicit TestHostFilter(std::string single_host_match) - : HostFilter(nullptr), single_host_match_(single_host_match) {} - - bool ContainsHostSuffix(const GURL& url) const override { - return single_host_match_ == url.host(); - } - - private: - std::string single_host_match_; -}; - class PreviewsHintsTest : public optimization_guide::ProtoDatabaseProviderTestBase { public:
diff --git a/components/security_state/content/content_utils.cc b/components/security_state/content/content_utils.cc index aa9fb9f..d05fdb1 100644 --- a/components/security_state/content/content_utils.cc +++ b/components/security_state/content/content_utils.cc
@@ -93,6 +93,21 @@ security_style_explanations->insecure_explanations.push_back(explanation); } +void ExplainSafetyTips( + const security_state::VisibleSecurityState& visible_security_state, + content::SecurityStyleExplanations* security_style_explanations) { + DCHECK_NE(visible_security_state.safety_tip_status, SAFETY_TIP_STATUS_NONE); + + security_style_explanations->summary = + l10n_util::GetStringUTF8(IDS_PAGE_INFO_SAFETY_TIP_SUMMARY); + // Add a bullet describing the issue. + content::SecurityStyleExplanation explanation( + l10n_util::GetStringUTF8(IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_TITLE), + l10n_util::GetStringUTF8( + IDS_PAGE_INFO_SAFETY_TIP_BAD_REPUTATION_DESCRIPTION)); + security_style_explanations->insecure_explanations.push_back(explanation); +} + void ExplainCertificateSecurity( const security_state::VisibleSecurityState& visible_security_state, content::SecurityStyleExplanations* security_style_explanations) { @@ -434,6 +449,9 @@ // certificate, connection, or content that needs to be explained, e.g. in // the case of a net error, so we can early return. return security_style; + } else if (visible_security_state.safety_tip_status != + security_state::SAFETY_TIP_STATUS_NONE) { + ExplainSafetyTips(visible_security_state, security_style_explanations); } else { ExplainHTTPSecurity(security_level, visible_security_state, security_style_explanations);
diff --git a/components/security_state/core/security_state.cc b/components/security_state/core/security_state.cc index b26d575..8abc28b 100644 --- a/components/security_state/core/security_state.cc +++ b/components/security_state/core/security_state.cc
@@ -194,6 +194,7 @@ VisibleSecurityState::VisibleSecurityState() : malicious_content_status(MALICIOUS_CONTENT_STATUS_NONE), + safety_tip_status(SAFETY_TIP_STATUS_NONE), connection_info_initialized(false), cert_status(0), connection_status(0),
diff --git a/components/security_state/core/security_state.h b/components/security_state/core/security_state.h index 955724e..2d95607c 100644 --- a/components/security_state/core/security_state.h +++ b/components/security_state/core/security_state.h
@@ -96,6 +96,13 @@ MALICIOUS_CONTENT_STATUS_BILLING, }; +// Describes whether the page triggers any safety tips or reputation +// warnings. +enum SafetyTipStatus { + SAFETY_TIP_STATUS_NONE, + SAFETY_TIP_STATUS_BAD_REPUTATION, +}; + // Contains the security state relevant to computing the SecurityLevel // for a page. This is the input to GetSecurityLevel(). struct VisibleSecurityState { @@ -105,6 +112,8 @@ MaliciousContentStatus malicious_content_status; + SafetyTipStatus safety_tip_status; + // CONNECTION SECURITY FIELDS // Whether the connection security fields are initialized. bool connection_info_initialized;
diff --git a/components/sessions/BUILD.gn b/components/sessions/BUILD.gn index 3c722ba..652e153 100644 --- a/components/sessions/BUILD.gn +++ b/components/sessions/BUILD.gn
@@ -111,6 +111,7 @@ public_deps = [ "//components/keyed_service/core", + "//skia", ] deps = [
diff --git a/components/sessions/core/DEPS b/components/sessions/core/DEPS index f2ecd68b..6c0a29a 100644 --- a/components/sessions/core/DEPS +++ b/components/sessions/core/DEPS
@@ -1,4 +1,7 @@ include_rules = [ "+components/keyed_service/core", "+components/prefs", + + # SkColor is referenced in a struct in session_types.h + "+third_party/skia/include/core/SkColor.h", ]
diff --git a/components/sessions/core/session_command.cc b/components/sessions/core/session_command.cc index 0f38cf7..7062332 100644 --- a/components/sessions/core/session_command.cc +++ b/components/sessions/core/session_command.cc
@@ -28,8 +28,8 @@ return true; } -base::Pickle* SessionCommand::PayloadAsPickle() const { - return new base::Pickle(contents(), static_cast<int>(size())); +std::unique_ptr<base::Pickle> SessionCommand::PayloadAsPickle() const { + return std::make_unique<base::Pickle>(contents(), static_cast<int>(size())); } } // namespace sessions
diff --git a/components/sessions/core/session_command.h b/components/sessions/core/session_command.h index 54d19e4..e5f7663 100644 --- a/components/sessions/core/session_command.h +++ b/components/sessions/core/session_command.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include "base/macros.h" @@ -60,11 +61,10 @@ // count is not equal to the size of data this command contains. bool GetPayload(void* dest, size_t count) const; - // Returns the contents as a pickle. It is up to the caller to delete the - // returned Pickle. The returned Pickle references the underlying data of - // this SessionCommand. If you need it to outlive the command, copy the - // pickle. - base::Pickle* PayloadAsPickle() const; + // Returns the contents as a pickle. The returned Pickle references the + // underlying data of this SessionCommand. If you need it to outlive the + // command, copy the pickle. + std::unique_ptr<base::Pickle> PayloadAsPickle() const; private: const id_type id_;
diff --git a/components/sessions/core/session_service_commands.cc b/components/sessions/core/session_service_commands.cc index 99a3301..e232d5c6e 100644 --- a/components/sessions/core/session_service_commands.cc +++ b/components/sessions/core/session_service_commands.cc
@@ -10,6 +10,7 @@ #include <utility> #include <vector> +#include "base/containers/flat_set.h" #include "base/memory/ptr_util.h" #include "base/pickle.h" #include "base/token.h" @@ -58,6 +59,7 @@ static const SessionCommand::id_type kCommandSetWindowWorkspace2 = 23; static const SessionCommand::id_type kCommandTabNavigationPathPruned = 24; static const SessionCommand::id_type kCommandSetTabGroup = 25; +static const SessionCommand::id_type kCommandSetTabGroupMetadata = 26; namespace { @@ -112,7 +114,7 @@ int32_t count; }; -struct SerializedTabGroupId { +struct SerializedToken { // These fields correspond to the high and low fields of |base::Token|. uint64_t id_high; uint64_t id_low; @@ -120,7 +122,7 @@ struct TabGroupPayload { SessionID::id_type tab_id; - SerializedTabGroupId maybe_group; + SerializedToken maybe_group; bool has_group; }; @@ -148,9 +150,6 @@ PERSISTED_SHOW_STATE_END = 8, }; -using IdToSessionTab = std::map<SessionID, std::unique_ptr<SessionTab>>; -using IdToSessionWindow = std::map<SessionID, std::unique_ptr<SessionWindow>>; - // Assert to ensure PersistedWindowShowState is updated if ui::WindowShowState // is changed. static_assert(ui::SHOW_STATE_END == @@ -217,6 +216,11 @@ } } +using IdToSessionTab = std::map<SessionID, std::unique_ptr<SessionTab>>; +using IdToSessionWindow = std::map<SessionID, std::unique_ptr<SessionWindow>>; +using TokenToSessionTabGroup = + std::map<base::Token, std::unique_ptr<SessionTabGroup>>; + // Returns the window in windows with the specified id. If a window does // not exist, one is created. SessionWindow* GetWindow(SessionID window_id, IdToSessionWindow* windows) { @@ -244,6 +248,17 @@ return i->second.get(); } +SessionTabGroup* GetTabGroup(base::Token group_id, + TokenToSessionTabGroup* groups) { + DCHECK(groups); + // For |group_id|, insert a corresponding group entry or get the existing one. + auto result = groups->emplace(group_id, nullptr); + TokenToSessionTabGroup::iterator it = result.first; + if (result.second) + it->second = std::make_unique<SessionTabGroup>(group_id); + return it->second.get(); +} + // Returns an iterator into navigations pointing to the navigation whose // index matches |index|. If no navigation index matches |index|, the first // navigation with an index > |index| is returned. @@ -312,9 +327,13 @@ // Adds tabs to their parent window based on the tab's window_id. This // ignores tabs with no navigations. -void AddTabsToWindows(IdToSessionTab* tabs, IdToSessionWindow* windows) { +void AddTabsToWindows(IdToSessionTab* tabs, + TokenToSessionTabGroup* tab_groups, + IdToSessionWindow* windows) { DVLOG(1) << "AddTabsToWindows"; - DVLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size(); + DVLOG(1) << "Tabs " << tabs->size() << ", groups " << tab_groups->size() + << ", windows " << windows->size(); + for (auto& tab_pair : *tabs) { std::unique_ptr<SessionTab> tab = std::move(tab_pair.second); if (!tab->window_id.id() || tab->navigations.empty()) @@ -339,6 +358,35 @@ // There are no more pointers left in |tabs|, just empty husks from the // move, so clear it out. tabs->clear(); + + // For each window, collect all the tab groups present. We rely on the fact + // that tab groups can't be split between windows. + for (auto& window_pair : *windows) { + SessionWindow* window = window_pair.second.get(); + + base::flat_set<base::Token> groups_in_current_window; + for (const auto& tab : window->tabs) { + if (tab->group.has_value()) + groups_in_current_window.insert(tab->group.value()); + } + + // Move corresponding SessionTabGroup entries into SessionWindow. + for (const base::Token& group_id : groups_in_current_window) { + auto it = tab_groups->find(group_id); + if (it == tab_groups->end()) { + window->tab_groups.push_back( + std::make_unique<SessionTabGroup>(group_id)); + continue; + } + window->tab_groups.push_back(std::move(it->second)); + tab_groups->erase(it); + } + } + + // We may have extraneous tab group entries. Since we don't have explicit + // commands for opening and closing tab groups, there may be dangling + // SessionTabGroup entries after all tabs in a group are closed. + tab_groups->clear(); } void ProcessTabNavigationPathPrunedCommand( @@ -376,6 +424,7 @@ bool CreateTabsAndWindows( const std::vector<std::unique_ptr<SessionCommand>>& data, IdToSessionTab* tabs, + TokenToSessionTabGroup* tab_groups, IdToSessionWindow* windows, SessionID* active_window_id) { // If the file is corrupt (command with wrong size, or unknown command), we @@ -573,6 +622,24 @@ break; } + case kCommandSetTabGroupMetadata: { + std::unique_ptr<base::Pickle> pickle = command->PayloadAsPickle(); + base::PickleIterator iter(*pickle); + + base::Optional<base::Token> group_id = ReadTokenFromPickle(&iter); + if (!group_id.has_value()) + return true; + + SessionTabGroup* group = GetTabGroup(group_id.value(), tab_groups); + + if (!iter.ReadString16(&group->title)) + return true; + + if (!iter.ReadUInt32(&group->color)) + return true; + break; + } + case kCommandSetPinnedState: { PinnedStatePayload payload; if (!command->GetPayload(&payload, sizeof(payload))) { @@ -788,6 +855,17 @@ return CreateSessionCommandForPayload(kCommandSetTabGroup, payload); } +std::unique_ptr<SessionCommand> CreateTabGroupMetadataUpdateCommand( + const base::Token& group, + const base::string16& title, + SkColor color) { + base::Pickle pickle; + WriteTokenToPickle(&pickle, group); + pickle.WriteString16(title); + pickle.WriteUInt32(color); + return std::make_unique<SessionCommand>(kCommandSetTabGroupMetadata, pickle); +} + std::unique_ptr<SessionCommand> CreatePinnedStateCommand( const SessionID& tab_id, bool is_pinned) { @@ -939,16 +1017,19 @@ std::vector<std::unique_ptr<SessionWindow>>* valid_windows, SessionID* active_window_id) { IdToSessionTab tabs; + TokenToSessionTabGroup tab_groups; IdToSessionWindow windows; DVLOG(1) << "RestoreSessionFromCommands " << commands.size(); - if (CreateTabsAndWindows(commands, &tabs, &windows, active_window_id)) { - AddTabsToWindows(&tabs, &windows); + if (CreateTabsAndWindows(commands, &tabs, &tab_groups, &windows, + active_window_id)) { + AddTabsToWindows(&tabs, &tab_groups, &windows); SortTabsBasedOnVisualOrderAndClear(&windows, valid_windows); UpdateSelectedTabIndex(valid_windows); } - // AddTabsToWindows should have processed all the tabs. + // AddTabsToWindows should have processed all the tabs and groups. DCHECK_EQ(0u, tabs.size()); + DCHECK_EQ(0u, tab_groups.size()); // SortTabsBasedOnVisualOrderAndClear should have processed all the windows. DCHECK_EQ(0u, windows.size()); }
diff --git a/components/sessions/core/session_service_commands.h b/components/sessions/core/session_service_commands.h index ce0a0c6..5715d6e 100644 --- a/components/sessions/core/session_service_commands.h +++ b/components/sessions/core/session_service_commands.h
@@ -49,6 +49,10 @@ SESSIONS_EXPORT std::unique_ptr<SessionCommand> CreateTabGroupCommand( const SessionID& tab_id, base::Optional<base::Token> group); +SESSIONS_EXPORT std::unique_ptr<SessionCommand> +CreateTabGroupMetadataUpdateCommand(const base::Token& group, + const base::string16& title, + SkColor color); SESSIONS_EXPORT std::unique_ptr<SessionCommand> CreatePinnedStateCommand( const SessionID& tab_id, bool is_pinned);
diff --git a/components/sessions/core/session_types.cc b/components/sessions/core/session_types.cc index 066099d..3c83c4f 100644 --- a/components/sessions/core/session_types.cc +++ b/components/sessions/core/session_types.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include "components/sessions/core/session_command.h" +#include "ui/gfx/color_palette.h" namespace sessions { @@ -22,6 +23,13 @@ SessionTab::~SessionTab() { } +// SessionTab ----------------------------------------------------------------- + +SessionTabGroup::SessionTabGroup(base::Token group_id) + : group_id(group_id), color(gfx::kPlaceholderColor) {} + +SessionTabGroup::~SessionTabGroup() {} + // SessionWindow --------------------------------------------------------------- SessionWindow::SessionWindow()
diff --git a/components/sessions/core/session_types.h b/components/sessions/core/session_types.h index b160f2e9..14864bf 100644 --- a/components/sessions/core/session_types.h +++ b/components/sessions/core/session_types.h
@@ -19,6 +19,7 @@ #include "components/sessions/core/session_id.h" #include "components/sessions/core/sessions_export.h" #include "components/variations/variations_associated_data.h" +#include "third_party/skia/include/core/SkColor.h" #include "ui/base/ui_base_types.h" #include "ui/gfx/geometry/rect.h" #include "url/gurl.h" @@ -97,6 +98,30 @@ DISALLOW_COPY_AND_ASSIGN(SessionTab); }; +// SessionTabGroup ----------------------------------------------------------- + +// Describes a tab group referenced by some SessionTab entry in its group +// field. By default, this is initialized with placeholder values that are +// visually obvious. +struct SESSIONS_EXPORT SessionTabGroup { + explicit SessionTabGroup(base::Token group); + ~SessionTabGroup(); + + // Uniquely identifies this group. Initialized to zero and must be set be + // user. Unlike SessionID this should be globally unique, even across + // different sessions. + base::Token group_id; + + // A human-readable title for the group. + base::string16 title; + + // An accent color used when displaying the group. + SkColor color; + + private: + DISALLOW_COPY_AND_ASSIGN(SessionTabGroup); +}; + // SessionWindow ------------------------------------------------------------- // Describes a saved window. @@ -145,6 +170,10 @@ // The tabs, ordered by visual order. std::vector<std::unique_ptr<SessionTab>> tabs; + // Tab groups in no particular order. For each group in |tab_groups|, there + // should be at least one tab in |tabs| in the group. + std::vector<std::unique_ptr<SessionTabGroup>> tab_groups; + // Is the window maximized, minimized, or normal? ui::WindowShowState show_state;
diff --git a/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc b/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc index f8e7348..7a7b07d 100644 --- a/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc +++ b/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc
@@ -22,10 +22,12 @@ #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" +#include "components/prefs/pref_service.h" #include "components/signin/internal/identity_manager/account_tracker_service.h" #include "components/signin/internal/identity_manager/oauth_multilogin_helper.h" #include "components/signin/internal/identity_manager/ubertoken_fetcher_impl.h" #include "components/signin/public/base/signin_metrics.h" +#include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h" #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_urls.h" @@ -438,13 +440,34 @@ fetcher_retries_(0), cookie_listener_binding_(this), external_cc_result_fetched_(false), - list_accounts_stale_(true) {} + list_accounts_stale_(true) { + std::string gaia_cookie_last_list_accounts_data = + signin_client_->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData); + + if (!gaia_cookie_last_list_accounts_data.empty()) { + if (!gaia::ParseListAccountsData(gaia_cookie_last_list_accounts_data, + &listed_accounts_, + &signed_out_accounts_)) { + DLOG(WARNING) << "GaiaCookieManagerService::ListAccounts: Failed to " + "parse list accounts data from pref."; + listed_accounts_.clear(); + signed_out_accounts_.clear(); + } + } +} GaiaCookieManagerService::~GaiaCookieManagerService() { CancelAll(); DCHECK(requests_.empty()); } +// static +void GaiaCookieManagerService::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterStringPref(prefs::kGaiaCookieLastListAccountsData, + std::string()); +} + void GaiaCookieManagerService::InitCookieListener() { DCHECK(!cookie_listener_binding_); network::mojom::CookieManager* cookie_manager = @@ -810,6 +833,8 @@ &signed_out_accounts_)) { listed_accounts_.clear(); signed_out_accounts_.clear(); + signin_client_->GetPrefs()->ClearPref( + prefs::kGaiaCookieLastListAccountsData); GoogleServiceAuthError error( GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE); RecordListAccountsFailure(error.state()); @@ -817,6 +842,8 @@ return; } + signin_client_->GetPrefs()->SetString(prefs::kGaiaCookieLastListAccountsData, + data); RecordListAccountsFailure(GoogleServiceAuthError::NONE); RecordListAccountsRetryResult(GoogleServiceAuthError::AuthErrorNone(), fetcher_retries_);
diff --git a/components/signin/internal/identity_manager/gaia_cookie_manager_service.h b/components/signin/internal/identity_manager/gaia_cookie_manager_service.h index c24edc3..193631a3 100644 --- a/components/signin/internal/identity_manager/gaia_cookie_manager_service.h +++ b/components/signin/internal/identity_manager/gaia_cookie_manager_service.h
@@ -18,6 +18,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/timer/timer.h" +#include "components/prefs/pref_registry_simple.h" #include "components/signin/internal/identity_manager/profile_oauth2_token_service.h" #include "components/signin/public/base/signin_client.h" #include "google_apis/gaia/gaia_auth_consumer.h" @@ -291,6 +292,9 @@ // Final call in the Setting accounts in cookie procedure. Public for testing. void OnSetAccountsFinished(signin::SetAccountsInCookieResult result); + // Registers prefs used by this class. + static void RegisterPrefs(PrefRegistrySimple* registry); + private: scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();
diff --git a/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc b/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc index 492ee78..c3c1d3b 100644 --- a/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc +++ b/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc
@@ -121,6 +121,7 @@ error_(GoogleServiceAuthError::SERVICE_ERROR), canceled_(GoogleServiceAuthError::REQUEST_CANCELED) { AccountTrackerService::RegisterPrefs(pref_service_.registry()); + GaiaCookieManagerService::RegisterPrefs(pref_service_.registry()); signin_client_ = std::make_unique<TestSigninClient>(&pref_service_); token_service_ = std::make_unique<FakeProfileOAuth2TokenService>(&pref_service_); @@ -650,6 +651,10 @@ ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); ASSERT_TRUE(list_accounts.empty()); ASSERT_TRUE(signed_out_accounts.empty()); + ASSERT_TRUE(signin_client() + ->GetPrefs() + ->GetString(prefs::kGaiaCookieLastListAccountsData) + .empty()); } TEST_F(GaiaCookieManagerServiceTest, ListAccountsFindsOneAccount) { @@ -675,9 +680,12 @@ ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); - SimulateListAccountsSuccess( - &helper, - "[\"f\", [[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]]]"); + std::string data = + "[\"f\", [[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]]]"; + SimulateListAccountsSuccess(&helper, data); + EXPECT_EQ(signin_client()->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData), + data); } TEST_F(GaiaCookieManagerServiceTest, ListAccountsFindsSignedOutAccounts) { @@ -709,12 +717,15 @@ ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); - SimulateListAccountsSuccess( - &helper, + std::string data = "[\"f\"," "[[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]," " [\"b\", 0, \"n\", \"c@d.com\", \"p\", 0, 0, 0, 0, 1, \"9\"," - "null,null,null,1]]]"); + "null,null,null,1]]]"; + SimulateListAccountsSuccess(&helper, data); + EXPECT_EQ(signin_client()->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData), + data); } TEST_F(GaiaCookieManagerServiceTest, ListAccountsAcceptsNull) { @@ -723,12 +734,12 @@ ASSERT_FALSE(helper.ListAccounts(nullptr, nullptr)); - SimulateListAccountsSuccess( - &helper, + std::string data = "[\"f\"," "[[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]," " [\"b\", 0, \"n\", \"c@d.com\", \"p\", 0, 0, 0, 0, 1, \"9\"," - "null,null,null,1]]]"); + "null,null,null,1]]]"; + SimulateListAccountsSuccess(&helper, data); std::vector<gaia::ListedAccount> signed_out_accounts; ASSERT_TRUE(helper.ListAccounts(nullptr, &signed_out_accounts)); @@ -737,6 +748,10 @@ std::vector<gaia::ListedAccount> accounts; ASSERT_TRUE(helper.ListAccounts(&accounts, nullptr)); ASSERT_EQ(1u, accounts.size()); + + EXPECT_EQ(signin_client()->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData), + data); } TEST_F(GaiaCookieManagerServiceTest, ListAccountsAfterOnCookieChange) { @@ -764,14 +779,18 @@ ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); ASSERT_TRUE(list_accounts.empty()); ASSERT_TRUE(signed_out_accounts.empty()); - SimulateListAccountsSuccess( - &helper, - "[\"f\", [[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]]]"); + + std::string data = + "[\"f\", [[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]]]"; + SimulateListAccountsSuccess(&helper, data); // Sanity-check that ListAccounts returns the cached data. ASSERT_TRUE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); ASSERT_TRUE(AreAccountListsEqual(nonempty_list_accounts, list_accounts)); ASSERT_TRUE(signed_out_accounts.empty()); + EXPECT_EQ(signin_client()->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData), + data); EXPECT_CALL(helper, StartFetchingListAccounts()); EXPECT_CALL(observer, @@ -789,7 +808,117 @@ ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); ASSERT_TRUE(AreAccountListsEqual(nonempty_list_accounts, list_accounts)); ASSERT_TRUE(signed_out_accounts.empty()); - SimulateListAccountsSuccess(&helper, "[\"f\",[]]"); + data = "[\"f\",[]]"; + SimulateListAccountsSuccess(&helper, data); + EXPECT_EQ(signin_client()->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData), + data); +} + +TEST_F(GaiaCookieManagerServiceTest, GaiaCookieLastListAccountsDataSaved) { + std::string data = + "[\"f\"," + "[[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]," + " [\"b\", 0, \"n\", \"c@d.com\", \"p\", 0, 0, 0, 0, 1, \"9\"," + "null,null,null,1]]]"; + std::vector<gaia::ListedAccount> expected_accounts; + gaia::ListedAccount listed_account; + listed_account.email = "a@b.com"; + listed_account.raw_email = "a@b.com"; + listed_account.gaia_id = "8"; + expected_accounts.push_back(listed_account); + + std::vector<gaia::ListedAccount> expected_signed_out_accounts; + gaia::ListedAccount signed_out_account; + signed_out_account.email = "c@d.com"; + signed_out_account.raw_email = "c@d.com"; + signed_out_account.gaia_id = "9"; + signed_out_account.signed_out = true; + expected_signed_out_accounts.push_back(signed_out_account); + std::vector<gaia::ListedAccount> list_accounts; + std::vector<gaia::ListedAccount> signed_out_accounts; + + { + InstrumentedGaiaCookieManagerService helper(token_service(), + signin_client()); + MockObserver observer(&helper); + + EXPECT_CALL(helper, StartFetchingListAccounts()); + EXPECT_CALL(observer, OnGaiaAccountsInCookieUpdated( + ListedAccountEquals(expected_accounts), + ListedAccountEquals(expected_signed_out_accounts), + no_error())); + + ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); + // |kGaiaCookieLastListAccountsData| is empty. + EXPECT_TRUE(list_accounts.empty()); + EXPECT_TRUE(signed_out_accounts.empty()); + SimulateListAccountsSuccess(&helper, data); + // |kGaiaCookieLastListAccountsData| is set. + ASSERT_EQ(signin_client()->GetPrefs()->GetString( + prefs::kGaiaCookieLastListAccountsData), + data); + // List accounts is not stale. + ASSERT_TRUE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); + } + + // Now that the list accounts data is saved to the pref service, test that + // starting a new Gaia Service Manager gives synchronous answers to list + // accounts. + { + InstrumentedGaiaCookieManagerService helper(token_service(), + signin_client()); + MockObserver observer(&helper); + EXPECT_CALL(helper, StartFetchingListAccounts()).Times(3); + + // Though |SimulateListAccountsSuccess| is not yet called, we are able to + // retrieve last |list_accounts| and |expected_accounts| from the pref, + // but mark them as stale. A |StartFetchingListAccounts| is triggered. + EXPECT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); + EXPECT_TRUE(AreAccountListsEqual(list_accounts, expected_accounts)); + EXPECT_TRUE(AreAccountListsEqual(signed_out_accounts, + expected_signed_out_accounts)); + + // |SimulateListAccountsSuccess| and assert list accounts is not stale + // anymore. + EXPECT_CALL(observer, OnGaiaAccountsInCookieUpdated( + ListedAccountEquals(expected_accounts), + ListedAccountEquals(expected_signed_out_accounts), + no_error())); + SimulateListAccountsSuccess(&helper, data); + ASSERT_TRUE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); + + // Change list account state to be stale, which will trigger list accounts + // request. + helper.ForceOnCookieChangeProcessing(); + + // Receive an unexpected response from the server. Listed accounts as well + // as the pref should be cleared. + expected_accounts.clear(); + expected_signed_out_accounts.clear(); + GoogleServiceAuthError error( + GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE); + EXPECT_CALL(observer, + OnGaiaAccountsInCookieUpdated( + ListedAccountEquals(expected_accounts), + ListedAccountEquals(expected_signed_out_accounts), error)); + SimulateListAccountsSuccess(&helper, "[]"); + EXPECT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts)); + // |kGaiaCookieLastListAccountsData| is cleared. + EXPECT_TRUE(signin_client() + ->GetPrefs() + ->GetString(prefs::kGaiaCookieLastListAccountsData) + .empty()); + } + + { + // On next startup, |kGaiaCookieLastListAccountsData| contains last list + // accounts data. + EXPECT_TRUE(signin_client() + ->GetPrefs() + ->GetString(prefs::kGaiaCookieLastListAccountsData) + .empty()); + } } TEST_F(GaiaCookieManagerServiceTest, ExternalCcResultFetcher) {
diff --git a/components/signin/public/base/signin_pref_names.cc b/components/signin/public/base/signin_pref_names.cc index 494ec235..0fe30da 100644 --- a/components/signin/public/base/signin_pref_names.cc +++ b/components/signin/public/base/signin_pref_names.cc
@@ -111,4 +111,8 @@ const char kTokenServiceExcludedSecondaryAccounts[] = "token_service.excluded_secondary_accounts"; +// Contains last |ListAccounts| data which corresponds to Gaia cookies. +const char kGaiaCookieLastListAccountsData[] = + "gaia_cookie.last_list_accounts_data"; + } // namespace prefs
diff --git a/components/signin/public/base/signin_pref_names.h b/components/signin/public/base/signin_pref_names.h index 01d8bab..26f1c460d 100644 --- a/components/signin/public/base/signin_pref_names.h +++ b/components/signin/public/base/signin_pref_names.h
@@ -30,6 +30,7 @@ extern const char kTokenServiceDiceCompatible[]; extern const char kTokenServiceExcludeAllSecondaryAccounts[]; extern const char kTokenServiceExcludedSecondaryAccounts[]; +extern const char kGaiaCookieLastListAccountsData[]; } // namespace prefs
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index 0574b8c..9c482d9a 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -418,6 +418,7 @@ PrimaryAccountManager::RegisterProfilePrefs(registry); AccountFetcherService::RegisterPrefs(registry); AccountTrackerService::RegisterPrefs(registry); + GaiaCookieManagerService::RegisterPrefs(registry); #if !defined(OS_ANDROID) && !defined(OS_IOS) MutableProfileOAuth2TokenServiceDelegate::RegisterProfilePrefs(registry); #endif
diff --git a/components/subresource_filter/content/browser/BUILD.gn b/components/subresource_filter/content/browser/BUILD.gn index 4b07091..d40f10a 100644 --- a/components/subresource_filter/content/browser/BUILD.gn +++ b/components/subresource_filter/content/browser/BUILD.gn
@@ -67,6 +67,8 @@ "async_document_subresource_filter_test_utils.h", "fake_safe_browsing_database_manager.cc", "fake_safe_browsing_database_manager.h", + "subframe_navigation_test_utils.cc", + "subframe_navigation_test_utils.h", "subresource_filter_observer_test_utils.cc", "subresource_filter_observer_test_utils.h", ] @@ -75,6 +77,8 @@ "//base/test:test_support", "//components/subresource_filter/core/common", "//content/public/browser", + "//content/test:test_support", + "//net", "//testing/gtest:gtest", "//url", ]
diff --git a/components/subresource_filter/content/browser/DEPS b/components/subresource_filter/content/browser/DEPS index 14df806e..bebcdf4 100644 --- a/components/subresource_filter/content/browser/DEPS +++ b/components/subresource_filter/content/browser/DEPS
@@ -2,6 +2,7 @@ "+components/safe_browsing/db", "+components/ukm", "+content/public/browser", + "+content/public/test", "+net/base", "+services/metrics/public/cpp", "+ui/base/page_transition_types.h",
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc index 51653d7..3a841a5 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager_unittest.cc
@@ -21,6 +21,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" +#include "components/subresource_filter/content/browser/subframe_navigation_test_utils.h" #include "components/subresource_filter/content/browser/subresource_filter_client.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_manager.h" #include "components/subresource_filter/content/common/subresource_filter_messages.h" @@ -223,13 +224,16 @@ void CreateTestNavigation(const GURL& url, content::RenderFrameHost* render_frame_host) { - DCHECK(!navigation_simulator_); DCHECK(render_frame_host); navigation_simulator_ = content::NavigationSimulator::CreateRendererInitiated( url, render_frame_host); } + content::NavigationSimulator* navigation_simulator() { + return navigation_simulator_.get(); + } + content::RenderFrameHost* CreateSubframeWithTestNavigation( const GURL& url, content::RenderFrameHost* parent) { @@ -240,58 +244,12 @@ return subframe; } - void SimulateStartAndExpectResult( - content::NavigationThrottle::ThrottleAction expect_result) { - navigation_simulator_->Start(); - content::NavigationThrottle::ThrottleCheckResult result = - navigation_simulator_->GetLastThrottleCheckResult(); - EXPECT_EQ(expect_result, result); - if (result.action() != content::NavigationThrottle::PROCEED) - navigation_simulator_.reset(); - } - - void SimulateRedirectAndExpectResult( - const GURL& new_url, - content::NavigationThrottle::ThrottleAction expect_result) { - navigation_simulator_->Redirect(new_url); - content::NavigationThrottle::ThrottleCheckResult result = - navigation_simulator_->GetLastThrottleCheckResult(); - EXPECT_EQ(expect_result, result); - if (result.action() != content::NavigationThrottle::PROCEED) - navigation_simulator_.reset(); - } - - // Returns the RenderFrameHost that the navigation commit in. - content::RenderFrameHost* SimulateCommitAndExpectResult( - content::NavigationThrottle::ThrottleAction expect_result) { - navigation_simulator_->Commit(); - content::NavigationThrottle::ThrottleCheckResult result = - navigation_simulator_->GetLastThrottleCheckResult(); - EXPECT_EQ(expect_result, result); - - auto scoped_simulator = std::move(navigation_simulator_); - if (result.action() == content::NavigationThrottle::PROCEED) - return scoped_simulator->GetFinalRenderFrameHost(); - return nullptr; - } - - void SimulateSameDocumentCommit() { - navigation_simulator_->CommitSameDocument(); - navigation_simulator_.reset(); - } - - void SimulateFailedNavigation(net::Error error) { - navigation_simulator_->Fail(error); - if (error != net::ERR_ABORTED) { - navigation_simulator_->CommitErrorPage(); - } - navigation_simulator_.reset(); - } - void NavigateAndCommitMainFrame(const GURL& url) { CreateTestNavigation(url, main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); } bool ManagerHasRulesetHandle() { @@ -387,8 +345,8 @@ // A disallowed subframe navigation should be successfully filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -406,8 +364,8 @@ // A disallowed subframe navigation should not be filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); - + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); EXPECT_EQ(0, disallowed_notification_count()); } @@ -420,9 +378,12 @@ // A disallowed subframe navigation should not be filtered in dry-run mode. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); // But it should still be activated. ExpectActivationSignalForFrame(child, true /* expect_activation */, true /* is_ad_subframe */); @@ -440,12 +401,12 @@ // filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/before-redirect.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - content::NavigationThrottle::ThrottleAction expected_action = - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE; - SimulateRedirectAndExpectResult( - GURL("https://www.example.com/disallowed.html"), expected_action); - + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateRedirectAndGetResult( + navigation_simulator(), + GURL("https://www.example.com/disallowed.html"))); EXPECT_EQ(1, disallowed_notification_count()); } @@ -458,11 +419,16 @@ // An allowed subframe navigation should complete successfully. CreateSubframeWithTestNavigation( GURL("https://www.example.com/allowed1.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - SimulateRedirectAndExpectResult(GURL("https://www.example.com/allowed2.html"), - content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateRedirectAndGetResult( + navigation_simulator(), + GURL("https://www.example.com/allowed2.html"))); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(child, true /* expect_activation */); EXPECT_EQ(0, disallowed_notification_count()); @@ -479,15 +445,15 @@ // A disallowed subframe navigation should be successfully filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/1/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); CreateSubframeWithTestNavigation( GURL("https://www.example.com/2/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -501,8 +467,8 @@ // A disallowed subframe navigation should be successfully filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/1/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); @@ -512,8 +478,8 @@ CreateSubframeWithTestNavigation( GURL("https://www.example.com/2/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(2, disallowed_notification_count()); } @@ -529,21 +495,21 @@ // A disallowed subframe navigation should be successfully filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/1/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); // Commit another navigation that triggers page level activation. GURL url2 = GURL(base::StringPrintf("%s#ref", kTestURLWithActivation)); CreateTestNavigation(url2, main_rfh()); - SimulateSameDocumentCommit(); + navigation_simulator()->CommitSameDocument(); ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */); CreateSubframeWithTestNavigation( GURL("https://www.example.com/2/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -560,9 +526,12 @@ // A subframe navigation should complete successfully. CreateSubframeWithTestNavigation(GURL("https://www.example.com/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(child, false /* expect_activation */); EXPECT_EQ(0, disallowed_notification_count()); @@ -576,8 +545,8 @@ CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); @@ -592,8 +561,8 @@ CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(2, disallowed_notification_count()); } @@ -618,9 +587,12 @@ // A subframe navigation should complete successfully. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(child, false /* expect_activation */); EXPECT_EQ(0, disallowed_notification_count()); @@ -636,15 +608,15 @@ GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation)); CreateTestNavigation(same_site_inactive_url, main_rfh()); - SimulateFailedNavigation(net::ERR_ABORTED); + SimulateFailedNavigation(navigation_simulator(), net::ERR_ABORTED); EXPECT_TRUE(ManagerHasRulesetHandle()); ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */); // A subframe navigation fail. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -659,15 +631,18 @@ GURL(base::StringPrintf("%sinactive.html", kTestURLWithActivation)); CreateTestNavigation(same_site_inactive_url, main_rfh()); - SimulateFailedNavigation(net::ERR_FAILED); + SimulateFailedNavigation(navigation_simulator(), net::ERR_FAILED); EXPECT_FALSE(ManagerHasRulesetHandle()); ExpectActivationSignalForFrame(main_rfh(), false /* expect_activation */); CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(child, false /* expect_activation */); EXPECT_EQ(0, disallowed_notification_count()); @@ -683,25 +658,31 @@ // filtering for this subframe document should still be activated. CreateSubframeWithTestNavigation(GURL("https://www.a.com/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* subframe1 = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe1, true /* expect_activation */); // Navigate a sub-subframe to a URL that is not itself disallowed. Subresource // filtering for this subframe document should still be activated. CreateSubframeWithTestNavigation(GURL("https://www.b.com/allowed.html"), subframe1); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* subframe2 = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe2, true /* expect_activation */); // A final, nested subframe navigation is filtered. CreateSubframeWithTestNavigation(GURL("https://www.c.com/disallowed.html"), subframe2); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -713,17 +694,23 @@ // Navigate a subframe that is not filtered, but should still activate. CreateSubframeWithTestNavigation(GURL("https://whitelist.com"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* subframe1 = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe1, true /* expect_activation */); // Navigate a sub-subframe that is not filtered due to the whitelist. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), subframe1); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* subframe2 = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe2, true /* expect_activation */); EXPECT_EQ(0, disallowed_notification_count()); @@ -731,16 +718,19 @@ // An identical series of events that don't match whitelist rules cause // filtering. CreateSubframeWithTestNavigation(GURL("https://average-joe.com"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* subframe3 = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe3, true /* expect_activation */); // Navigate a sub-subframe that is not filtered due to the whitelist. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), subframe3); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -763,9 +753,12 @@ CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(child, false /* expect_activation */); EXPECT_EQ(0, disallowed_notification_count()); @@ -796,9 +789,12 @@ // Navigate a subframe that is not filtered, but should still activate. CreateSubframeWithTestNavigation(GURL("https://whitelist.com"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* subframe1 = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe1, true /* expect_activation */); tester.ExpectTotalCount(kActivationStateHistogram, 3); @@ -823,9 +819,8 @@ // A disallowed subframe navigation should be successfully filtered. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_EQ(1, disallowed_notification_count()); } @@ -845,9 +840,11 @@ throttle_manager()->OnFrameIsAdSubframe(subframe); EXPECT_TRUE(throttle_manager()->IsFrameTaggedAsAd(subframe)); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - subframe = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + subframe = navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(subframe); ExpectActivationSignalForFrame(subframe, true /* expect_activation */, true /* is_ad_subframe */); @@ -855,9 +852,9 @@ // A non-ad navigation for the same frame should be considered an ad // subframe as well. CreateTestNavigation(GURL("https://example.com/allowed2.html"), subframe); - subframe = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); - EXPECT_TRUE(subframe); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + subframe = navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe, true /* expect_activation */, true /* is_ad_subframe */); } @@ -882,10 +879,13 @@ throttle_manager()->OnFrameIsAdSubframe(initial_subframe); EXPECT_TRUE(throttle_manager()->IsFrameTaggedAsAd(initial_subframe)); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* final_subframe = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(final_subframe); EXPECT_NE(initial_subframe, final_subframe); @@ -910,19 +910,22 @@ // Simulate the render process telling the manager that the frame is an ad. throttle_manager()->OnFrameIsAdSubframe(subframe); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - - subframe = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + subframe = navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(subframe, true /* expect_activation */, true /* is_ad_subframe */); // Create a grandchild frame that is marked as an ad because its parent is. content::RenderFrameHost* grandchild_frame = CreateSubframeWithTestNavigation( GURL("https://www.example.com/foo/allowed.html"), subframe); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - grandchild_frame = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + grandchild_frame = navigation_simulator()->GetFinalRenderFrameHost(); ExpectActivationSignalForFrame(grandchild_frame, true /* expect_activation */, true /* is_ad_subframe */); EXPECT_TRUE(throttle_manager()->IsFrameTaggedAsAd(grandchild_frame)); @@ -942,9 +945,12 @@ // A disallowed subframe navigation should not be filtered in dry-run mode. CreateSubframeWithTestNavigation( GURL("https://www.example.com/disallowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(child); // But it should still be activated. @@ -956,9 +962,12 @@ // tagged as ad because of its parent. CreateSubframeWithTestNavigation( GURL("https://www.example.com/allowed_by_ruleset.html"), child); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* grandchild = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(grandchild); ExpectActivationSignalForFrame(grandchild, true /* expect_activation */, true /* is_ad_subframe */); @@ -968,9 +977,12 @@ CreateSubframeWithTestNavigation( GURL("https://www.example.com/great_grandchild_allowed_by_ruleset.html"), child); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* greatGrandchild = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(greatGrandchild); ExpectActivationSignalForFrame(greatGrandchild, true /* expect_activation */, true /* is_ad_subframe */); @@ -986,9 +998,12 @@ CreateSubframeWithTestNavigation( GURL("https://www.example.com/allowed_by_ruleset.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* child = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(child); ExpectActivationSignalForFrame(child, true /* expect_activation */, false /* is_ad_subframe */); @@ -998,9 +1013,12 @@ // as ad because its parent is not tagged as well. CreateSubframeWithTestNavigation( GURL("https://www.example.com/also_allowed_by_ruleset.html"), child); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); content::RenderFrameHost* grandchild = - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + navigation_simulator()->GetFinalRenderFrameHost(); EXPECT_TRUE(grandchild); ExpectActivationSignalForFrame(grandchild, true /* expect_activation */, false /* is_ad_subframe */);
diff --git a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc index 49b40db..513f720f 100644 --- a/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc +++ b/components/subresource_filter/content/browser/subframe_navigation_filtering_throttle_unittest.cc
@@ -16,6 +16,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter.h" #include "components/subresource_filter/content/browser/async_document_subresource_filter_test_utils.h" +#include "components/subresource_filter/content/browser/subframe_navigation_test_utils.h" #include "components/subresource_filter/content/browser/subresource_filter_observer_test_utils.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" #include "components/subresource_filter/core/common/test_ruleset_creator.h" @@ -127,32 +128,6 @@ render_frame); } - void SimulateStartAndExpectResult( - content::NavigationThrottle::ThrottleAction expect_result) { - navigation_simulator_->Start(); - EXPECT_EQ(expect_result, - navigation_simulator_->GetLastThrottleCheckResult()); - } - - void SimulateRedirectAndExpectResult( - const GURL& new_url, - content::NavigationThrottle::ThrottleAction expect_result) { - navigation_simulator_->Redirect(new_url); - EXPECT_EQ(expect_result, - navigation_simulator_->GetLastThrottleCheckResult()); - } - - void SimulateCommitAndExpectResult( - content::NavigationThrottle::ThrottleAction expect_result) { - navigation_simulator_->Commit(); - EXPECT_EQ(expect_result, - navigation_simulator_->GetLastThrottleCheckResult()); - } - - void SimulateCommitErrorPage() { - navigation_simulator_->CommitErrorPage(); - } - const std::vector<std::string>& GetConsoleMessages() { return content::RenderFrameHostTester::For(main_rfh()) ->GetConsoleMessages(); @@ -182,8 +157,8 @@ InitializeDocumentSubresourceFilter(GURL("https://example.test")); const GURL url("https://example.test/disallowed.html"); CreateTestSubframeAndInitNavigation(url, main_rfh()); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_TRUE( base::Contains(GetConsoleMessages(), GetFilterConsoleMessage(url))); } @@ -193,11 +168,12 @@ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - content::NavigationThrottle::ThrottleAction expected_result = - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE; - SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"), - expected_result); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateRedirectAndGetResult( + navigation_simulator(), + GURL("https://example.test/disallowed.html"))); } TEST_F(SubframeNavigationFilteringThrottleTest, DryRunOnStart) { @@ -206,7 +182,8 @@ const GURL url("https://example.test/disallowed.html"); CreateTestSubframeAndInitNavigation(url, main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); EXPECT_FALSE( base::Contains(GetConsoleMessages(), GetFilterConsoleMessage(url))); } @@ -217,9 +194,12 @@ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"), - content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateRedirectAndGetResult( + navigation_simulator(), + GURL("https://example.test/disallowed.html"))); } TEST_F(SubframeNavigationFilteringThrottleTest, FilterOnSecondRedirect) { @@ -227,13 +207,16 @@ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - SimulateRedirectAndExpectResult(GURL("https://example.test/allowed2.html"), - content::NavigationThrottle::PROCEED); - content::NavigationThrottle::ThrottleAction expected_result = - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE; - SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"), - expected_result); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ( + content::NavigationThrottle::PROCEED, + SimulateRedirectAndGetResult(navigation_simulator(), + GURL("https://example.test/allowed2.html"))); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateRedirectAndGetResult( + navigation_simulator(), + GURL("https://example.test/disallowed.html"))); } TEST_F(SubframeNavigationFilteringThrottleTest, NeverFilterNonMatchingRule) { @@ -241,10 +224,14 @@ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - SimulateRedirectAndExpectResult(GURL("https://example.test/allowed2.html"), - content::NavigationThrottle::PROCEED); - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ( + content::NavigationThrottle::PROCEED, + SimulateRedirectAndGetResult(navigation_simulator(), + GURL("https://example.test/allowed2.html"))); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); } TEST_F(SubframeNavigationFilteringThrottleTest, FilterSubsubframe) { @@ -261,8 +248,8 @@ CreateTestSubframeAndInitNavigation( GURL("https://example.test/disallowed.html"), parent_subframe); - SimulateStartAndExpectResult( - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateStartAndGetResult(navigation_simulator())); } TEST_F(SubframeNavigationFilteringThrottleTest, DelayMetrics) { @@ -271,12 +258,14 @@ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), main_rfh()); navigation_simulator()->SetTransition(ui::PAGE_TRANSITION_MANUAL_SUBFRAME); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - content::NavigationThrottle::ThrottleAction expected_result = - content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE; - SimulateRedirectAndExpectResult(GURL("https://example.test/disallowed.html"), - expected_result); - SimulateCommitErrorPage(); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, + SimulateRedirectAndGetResult( + navigation_simulator(), + GURL("https://example.test/disallowed.html"))); + + navigation_simulator()->CommitErrorPage(); const char kFilterDelayDisallowed[] = "SubresourceFilter.DocumentLoad.SubframeFilteringDelay.Disallowed"; @@ -287,8 +276,11 @@ CreateTestSubframeAndInitNavigation(GURL("https://example.test/allowed.html"), main_rfh()); - SimulateStartAndExpectResult(content::NavigationThrottle::PROCEED); - SimulateCommitAndExpectResult(content::NavigationThrottle::PROCEED); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateStartAndGetResult(navigation_simulator())); + EXPECT_EQ(content::NavigationThrottle::PROCEED, + SimulateCommitAndGetResult(navigation_simulator())); + histogram_tester.ExpectTotalCount(kFilterDelayDisallowed, 1); histogram_tester.ExpectTotalCount(kFilterDelayAllowed, 1); }
diff --git a/components/subresource_filter/content/browser/subframe_navigation_test_utils.cc b/components/subresource_filter/content/browser/subframe_navigation_test_utils.cc new file mode 100644 index 0000000..1549ba6 --- /dev/null +++ b/components/subresource_filter/content/browser/subframe_navigation_test_utils.cc
@@ -0,0 +1,42 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/subresource_filter/content/browser/subframe_navigation_test_utils.h" + +#include "content/public/browser/navigation_handle.h" +#include "content/public/test/navigation_simulator.h" +#include "net/base/net_errors.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace subresource_filter { + +content::NavigationThrottle::ThrottleCheckResult SimulateStartAndGetResult( + content::NavigationSimulator* navigation_simulator) { + navigation_simulator->Start(); + return navigation_simulator->GetLastThrottleCheckResult(); +} + +content::NavigationThrottle::ThrottleCheckResult SimulateRedirectAndGetResult( + content::NavigationSimulator* navigation_simulator, + const GURL& new_url) { + navigation_simulator->Redirect(new_url); + return navigation_simulator->GetLastThrottleCheckResult(); +} + +content::NavigationThrottle::ThrottleCheckResult SimulateCommitAndGetResult( + content::NavigationSimulator* navigation_simulator) { + navigation_simulator->Commit(); + return navigation_simulator->GetLastThrottleCheckResult(); +} + +void SimulateFailedNavigation( + content::NavigationSimulator* navigation_simulator, + net::Error error) { + navigation_simulator->Fail(error); + if (error != net::ERR_ABORTED) { + navigation_simulator->CommitErrorPage(); + } +} + +} // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/subframe_navigation_test_utils.h b/components/subresource_filter/content/browser/subframe_navigation_test_utils.h new file mode 100644 index 0000000..c8ca5bf --- /dev/null +++ b/components/subresource_filter/content/browser/subframe_navigation_test_utils.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBFRAME_NAVIGATION_TEST_UTILS_H_ +#define COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBFRAME_NAVIGATION_TEST_UTILS_H_ + +#include "content/public/browser/navigation_throttle.h" +#include "net/base/net_errors.h" +#include "url/gurl.h" + +namespace content { +class NavigationSimulator; +} + +namespace subresource_filter { + +content::NavigationThrottle::ThrottleCheckResult SimulateStartAndGetResult( + content::NavigationSimulator* navigation_simulator); + +content::NavigationThrottle::ThrottleCheckResult SimulateRedirectAndGetResult( + content::NavigationSimulator* navigation_simulator, + const GURL& new_url); + +content::NavigationThrottle::ThrottleCheckResult SimulateCommitAndGetResult( + content::NavigationSimulator* navigation_simulator); + +void SimulateFailedNavigation( + content::NavigationSimulator* navigation_simulator, + net::Error error); + +} // namespace subresource_filter + +#endif // COMPONENTS_SUBRESOURCE_FILTER_CONTENT_BROWSER_SUBFRAME_NAVIGATION_TEST_UTILS_H_
diff --git a/components/sync/driver/data_type_controller.h b/components/sync/driver/data_type_controller.h index d2fca1b8..c7339084 100644 --- a/components/sync/driver/data_type_controller.h +++ b/components/sync/driver/data_type_controller.h
@@ -117,6 +117,8 @@ // DataTypeManager before downloading initial data. Non-blocking types need to // pass activation context containing progress marker to sync backend and use // |set_downloaded| to inform the manager whether their initial sync is done. + // TODO(treib): Make this synchronous and possibly merge with + // ActivateManuallyForNigori(). virtual void RegisterWithBackend( base::OnceCallback<void(bool)> set_downloaded, ModelTypeConfigurer* configurer) = 0;
diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc index 702c5a8d..aa4ac89 100644 --- a/components/sync/driver/data_type_manager_impl.cc +++ b/components/sync/driver/data_type_manager_impl.cc
@@ -209,6 +209,11 @@ base::Bind(&DataTypeManagerImpl::SetTypeDownloaded, base::Unretained(this), dtc->type()), configurer_); + // This assumes SetTypeDownloaded() is called synchronously, which is + // the case. + if (force_redownload_types_.Has(type)) { + downloaded_types_.Remove(type); + } } } } @@ -391,7 +396,15 @@ data_type_status_table_.ResetDataTypePolicyErrorFor(type); const bool unready_status_changed = data_type_status_table_.ResetUnreadyErrorFor(type); - return data_type_policy_error_changed || unready_status_changed; + if (!data_type_policy_error_changed && !unready_status_changed) { + // Nothing changed. + return false; + } + // If preconditions are newly met, the datatype should be immediately + // redownloaded as part of the datatype configuration (most relevant for + // the UNREADY_ERROR case which usually won't clear sync metadata). + force_redownload_types_.Put(type); + return true; } case DataTypeController::PreconditionState::kMustStopAndClearData: { @@ -581,6 +594,8 @@ if (!types_to_download.Empty()) types_to_download.Put(NIGORI); + force_redownload_types_.RemoveAll(types_to_download); + // TODO(sync): crbug.com/137550. // It's dangerous to configure types that have progress markers. Types with // progress markers can trigger a MIGRATION_DONE response. We are not
diff --git a/components/sync/driver/data_type_manager_impl.h b/components/sync/driver/data_type_manager_impl.h index 99d4291..705abeee 100644 --- a/components/sync/driver/data_type_manager_impl.h +++ b/components/sync/driver/data_type_manager_impl.h
@@ -206,6 +206,13 @@ // |model_association_manager_| was last attempted. ModelTypeSet last_enabled_types_; + // A set of types that should be redownloaded even if initial sync is + // completed for them. + // TODO(crbug.com/967677): Once all datatypes are in USS, we should redesign + // this class and for example compute |downloaded_types_|'s initial value + // only after all datatypes have loaded for the first time. + ModelTypeSet force_redownload_types_; + // Whether an attempt to reconfigure was made while we were busy configuring. // The |last_requested_types_| will reflect the newest set of requested types. bool needs_reconfigure_;
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc index 00663fa9..4535273 100644 --- a/components/sync/engine_impl/model_type_registry.cc +++ b/components/sync/engine_impl/model_type_registry.cc
@@ -260,16 +260,6 @@ return result; } -ModelTypeSet ModelTypeRegistry::GetInitialSyncDoneNonBlockingTypes() const { - ModelTypeSet types; - for (const auto& worker : model_type_workers_) { - if (worker->IsInitialSyncEnded()) { - types.Put(worker->GetModelType()); - } - } - return types; -} - const UpdateHandler* ModelTypeRegistry::GetUpdateHandler(ModelType type) const { auto it = update_handler_map_.find(type); return it == update_handler_map_.end() ? nullptr : it->second;
diff --git a/components/sync/engine_impl/model_type_registry.h b/components/sync/engine_impl/model_type_registry.h index 174e8cb..b04821e 100644 --- a/components/sync/engine_impl/model_type_registry.h +++ b/components/sync/engine_impl/model_type_registry.h
@@ -94,9 +94,6 @@ // applied. ModelTypeSet GetInitialSyncEndedTypes() const; - // Returns the set of non-blocking types with initial sync done. - ModelTypeSet GetInitialSyncDoneNonBlockingTypes() const; - // Returns the update handler for |type|. const UpdateHandler* GetUpdateHandler(ModelType type) const;
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc index 14fcd0e..fb01ab2 100644 --- a/components/sync/engine_impl/model_type_worker.cc +++ b/components/sync/engine_impl/model_type_worker.cc
@@ -378,12 +378,6 @@ void ModelTypeWorker::PassiveApplyUpdates(StatusController* status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - // This should only be called at the end of the very first download cycle, - // except for NIGORI, which can be downloaded in multiple configuration sync - // cycles and hence repeatedly ends up in PassiveApplyUpdates(). - DCHECK(type_ == NIGORI || !model_type_state_.initial_sync_done()) - << "PassiveApplyUpdates() called after initial sync has been done for " - << ModelTypeToString(type_); // Indicate to the processor that the initial download is done. The initial // sync technically isn't done yet but by the time this value is persisted to // disk on the model thread it will be.
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index cd300d3..49d3a4cb 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -242,14 +242,6 @@ DCHECK(!ready_task.is_null()); DCHECK(initialized_); - // Don't download non-blocking types that have already completed initial sync. - ModelTypeSet to_remove = - model_type_registry_->GetInitialSyncDoneNonBlockingTypes(); - // NIGORI is the exception, because we may want to download it several times - // during configuration (see DataTypeManagerImpl::PrepareConfigureParams()). - to_remove.Remove(NIGORI); - to_download.RemoveAll(to_remove); - DVLOG(1) << "Configuring -" << "\n\t" << "types to download: " << ModelTypeSetToString(to_download);
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index b9f2c53..27d4d3b 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -75,9 +75,42 @@ } // namespace -std::string SurfaceAggregator::ClipData::ToString() const { - return is_clipped ? "clip " + rect.ToString() : "no clip"; -} +struct SurfaceAggregator::ClipData { + std::string ToString() const { + return is_clipped ? "clip " + rect.ToString() : "no clip"; + } + + bool is_clipped = false; + gfx::Rect rect; +}; + +struct SurfaceAggregator::PrewalkResult { + // This is the set of Surfaces that were referenced by another Surface, but + // not included in a SurfaceDrawQuad. + base::flat_set<SurfaceId> undrawn_surfaces; + bool may_contain_video = false; +}; + +struct SurfaceAggregator::RoundedCornerInfo { + RoundedCornerInfo() = default; + + // |target_transform| is the transform that maps |bounds_arg| from its current + // space into the desired target space. It must be a scale+translation matrix. + RoundedCornerInfo(const gfx::RRectF& bounds_arg, + bool is_fast_rounded_corner, + const gfx::Transform target_transform) + : bounds(bounds_arg), is_fast_rounded_corner(is_fast_rounded_corner) { + if (bounds.IsEmpty()) + return; + DCHECK(target_transform.Preserves2dAxisAlignment()); + SkMatrix matrix = target_transform.matrix(); + bounds.Scale(matrix.getScaleX(), matrix.getScaleY()); + bounds.Offset(target_transform.To2dTranslation()); + } + + gfx::RRectF bounds; + bool is_fast_rounded_corner; +}; SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager, DisplayResourceProvider* provider, @@ -99,10 +132,6 @@ ProcessAddedAndRemovedSurfaces(); } -SurfaceAggregator::PrewalkResult::PrewalkResult() {} - -SurfaceAggregator::PrewalkResult::~PrewalkResult() {} - // Create a clip rect for an aggregated quad from the original clip rect and // the clip rect from the surface it's on. SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect( @@ -487,9 +516,9 @@ CopyQuadsToPass(source.quad_list, source.shared_quad_state_list, surface->GetActiveFrame().device_scale_factor(), - child_to_parent_map, gfx::Transform(), ClipData(), - copy_pass.get(), surface_id, RoundedCornerInfo(), - occluding_damage_rect, occluding_damage_rect_valid); + child_to_parent_map, gfx::Transform(), {}, copy_pass.get(), + surface_id, RoundedCornerInfo(), occluding_damage_rect, + occluding_damage_rect_valid); // If the render pass has copy requests, or should be cached, or has // moving-pixel filters, or in a moving-pixel surface, we should damage the @@ -528,9 +557,9 @@ // Intersect the transformed visible rect and the clip rect to create a // smaller cliprect for the quad. - ClipData surface_quad_clip_rect( + ClipData surface_quad_clip_rect = { true, cc::MathUtil::MapEnclosingClippedRect( - source_sqs->quad_to_target_transform, source_visible_rect)); + source_sqs->quad_to_target_transform, source_visible_rect)}; if (source_sqs->is_clipped) { surface_quad_clip_rect.rect.Intersect(source_sqs->clip_rect); } @@ -572,8 +601,7 @@ /* backdrop_filter_quality*/ 1.0f); } - // Need to re-query since referenced_surfaces_ iterators are not stable. - referenced_surfaces_.erase(referenced_surfaces_.find(surface_id)); + referenced_surfaces_.erase(surface_id); } void SurfaceAggregator::EmitDefaultBackgroundColorQuad( @@ -772,20 +800,6 @@ occluding_damage_rect_valid); } -SurfaceAggregator::RoundedCornerInfo::RoundedCornerInfo( - const gfx::RRectF& bounds_arg, - bool is_fast_rounded_corner_arg, - const gfx::Transform target_transform) { - is_fast_rounded_corner = is_fast_rounded_corner_arg; - if (bounds_arg.IsEmpty()) - return; - DCHECK(target_transform.Preserves2dAxisAlignment()); - bounds = bounds_arg; - SkMatrix matrix = target_transform.matrix(); - bounds.Scale(matrix.getScaleX(), matrix.getScaleY()); - bounds.Offset(target_transform.To2dTranslation()); -} - SharedQuadState* SurfaceAggregator::CopyAndScaleSharedQuadState( const SharedQuadState* source_sqs, const gfx::Transform& scaled_quad_to_target_transform, @@ -799,7 +813,7 @@ bool occluding_damage_rect_valid) { auto* shared_quad_state = dest_render_pass->CreateAndAppendSharedQuadState(); ClipData new_clip_rect = CalculateClipRect( - clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect), + clip_rect, {source_sqs->is_clipped, source_sqs->clip_rect}, target_transform); // target_transform contains any transformation that may exist @@ -868,7 +882,7 @@ // Both cannot be set at once. If this happens then a surface is being // merged when it should not. DCHECK(quad->shared_quad_state->rounded_corner_bounds.IsEmpty() || - parent_rounded_corner_info.IsEmpty()); + parent_rounded_corner_info.bounds.IsEmpty()); if (quad->material == DrawQuad::Material::kSurfaceContent) { const auto* surface_quad = SurfaceDrawQuad::MaterialCast(quad); @@ -879,7 +893,7 @@ if (!surface_quad->surface_range.end().is_valid()) continue; - if (parent_rounded_corner_info.IsEmpty()) { + if (parent_rounded_corner_info.bounds.IsEmpty()) { new_rounded_corner_info = RoundedCornerInfo( quad->shared_quad_state->rounded_corner_bounds, quad->shared_quad_state->is_fast_rounded_corner, target_transform); @@ -891,7 +905,7 @@ &damage_rect_in_quad_space_valid, new_rounded_corner_info); } else { if (quad->shared_quad_state != last_copied_source_shared_quad_state) { - if (parent_rounded_corner_info.IsEmpty()) { + if (parent_rounded_corner_info.bounds.IsEmpty()) { new_rounded_corner_info = RoundedCornerInfo(quad->shared_quad_state->rounded_corner_bounds, quad->shared_quad_state->is_fast_rounded_corner, @@ -1040,7 +1054,7 @@ frame.device_scale_factor(), child_to_parent_map, apply_surface_transform_to_root_pass ? surface_transform : gfx::Transform(), - ClipData(), copy_pass.get(), surface->surface_id(), + {}, copy_pass.get(), surface->surface_id(), RoundedCornerInfo(), occluding_damage_rect, occluding_damage_rect_valid); @@ -1372,8 +1386,7 @@ has_cached_render_passes_ = true; } - auto it = referenced_surfaces_.find(surface->surface_id()); - referenced_surfaces_.erase(it); + referenced_surfaces_.erase(surface->surface_id()); if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video) result->may_contain_video = true; @@ -1417,8 +1430,7 @@ prewalk_result->undrawn_surfaces.erase(surface_id); referenced_surfaces_.insert(surface_id); CopyPasses(surface->GetActiveFrame(), surface); - // CopyPasses may have mutated container, need to re-query to erase. - referenced_surfaces_.erase(referenced_surfaces_.find(surface_id)); + referenced_surfaces_.erase(surface_id); } } } @@ -1444,7 +1456,7 @@ const RoundedCornerInfo& rounded_corner_info, const RenderPass& root_render_pass) { // If the quad has no rounded corner, then we do not have to block merging. - if (rounded_corner_info.IsEmpty()) + if (rounded_corner_info.bounds.IsEmpty()) return true; // If the quad has rounded corner and it is not a fast rounded corner, we @@ -1518,8 +1530,7 @@ CopyUndrawnSurfaces(&prewalk_result); referenced_surfaces_.insert(surface_id); CopyPasses(root_surface_frame, surface); - // CopyPasses may have mutated container, need to re-query to erase. - referenced_surfaces_.erase(referenced_surfaces_.find(surface_id)); + referenced_surfaces_.erase(surface_id); AddColorConversionPass(); moved_pixel_passes_.clear();
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h index 9012e6d..085527e68 100644 --- a/components/viz/service/display/surface_aggregator.h +++ b/components/viz/service/display/surface_aggregator.h
@@ -75,25 +75,9 @@ void SetFrameAnnotator(std::unique_ptr<FrameAnnotator> frame_annotator); private: - struct ClipData { - ClipData() : is_clipped(false) {} - ClipData(bool is_clipped, const gfx::Rect& rect) - : is_clipped(is_clipped), rect(rect) {} - - std::string ToString() const; - - bool is_clipped; - gfx::Rect rect; - }; - - struct PrewalkResult { - PrewalkResult(); - ~PrewalkResult(); - // This is the set of Surfaces that were referenced by another Surface, but - // not included in a SurfaceDrawQuad. - base::flat_set<SurfaceId> undrawn_surfaces; - bool may_contain_video = false; - }; + struct ClipData; + struct PrewalkResult; + struct RoundedCornerInfo; struct RenderPassInfo { // This is the id the pass is mapped to. @@ -102,20 +86,6 @@ bool in_use = true; }; - struct RoundedCornerInfo { - RoundedCornerInfo() : is_fast_rounded_corner(false) {} - // |target_transform| is the transform that maps |bounds| from its current - // space into the desired target space. It must be a scale+translation - // matrix. - RoundedCornerInfo(const gfx::RRectF& bounds, - bool is_fast_rounded_corner, - const gfx::Transform target_transform); - - bool IsEmpty() const { return bounds.IsEmpty(); } - gfx::RRectF bounds; - bool is_fast_rounded_corner; - }; - ClipData CalculateClipRect(const ClipData& surface_clip, const ClipData& quad_clip, const gfx::Transform& target_transform);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 97a3a70e..fb4db9f9 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1789,6 +1789,8 @@ "storage_partition_impl_map.h", "system_connector_impl.cc", "system_connector_impl.h", + "theme_helper.cc", + "theme_helper.h", "theme_helper_mac.h", "theme_helper_mac.mm", "tracing/background_memory_tracing_observer.cc",
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 5bf01d1..4e7e971 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc
@@ -194,6 +194,10 @@ GetRole() == ax::mojom::Role::kWebArea; } +bool BrowserAccessibility::IsIgnored() const { + return node()->IsIgnored(); +} + bool BrowserAccessibility::IsTextOnlyObject() const { return node_ && node_->IsText(); } @@ -1106,7 +1110,7 @@ } std::string BrowserAccessibility::GetLiveRegionText() const { - if (GetRole() == ax::mojom::Role::kIgnored) + if (IsIgnored()) return ""; std::string text = GetStringAttribute(ax::mojom::StringAttribute::kName); @@ -1373,7 +1377,7 @@ const std::vector<gfx::NativeViewAccessible> BrowserAccessibility::GetDescendants() const { std::vector<gfx::NativeViewAccessible> descendants; - if (!HasState(ax::mojom::State::kIgnored) && PlatformChildCount() > 0) { + if (!IsIgnored() && PlatformChildCount() > 0) { BrowserAccessibility* next_sibling_node = PlatformGetNextSibling(); BrowserAccessibility* next_descendant_node = BrowserAccessibilityManager::NextInTreeOrder(this);
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index 820d81d01..182f378 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -106,6 +106,8 @@ bool IsEditField() const; + bool IsIgnored() const; + // Returns true if this object is used only for representing text. bool IsTextOnlyObject() const;
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index 899e66d..6432891 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -1718,7 +1718,7 @@ win_attributes_->value = GetValue(); - win_attributes_->ignored = owner()->HasState(ax::mojom::State::kIgnored); + win_attributes_->ignored = owner()->IsIgnored(); } void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() { @@ -1728,7 +1728,7 @@ void BrowserAccessibilityComWin::UpdateStep3FireEvents( bool is_subtree_creation) { int32_t state = MSAAState(); - const bool ignored = owner()->HasState(ax::mojom::State::kIgnored); + const bool ignored = owner()->IsIgnored(); // Suppress all of these events when the node is ignored, or when the ignored // state has changed.
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc index 8d7b38ee..78cdfdf 100644 --- a/content/browser/accessibility/browser_accessibility_manager_auralinux.cc +++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.cc
@@ -158,7 +158,7 @@ // Since AuraLinux needs to send the children-changed::add event with the // index in parent, the event must be fired after the node is unignored. // children-changed:remove is handled in |OnStateChanged| - if (!node->HasState(ax::mojom::State::kIgnored)) { + if (!node->IsIgnored()) { if (node->IsNative() && node->GetParent()) { g_signal_emit_by_name(node->GetParent(), "children-changed::add", node->GetIndexInParent(),
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 5b1efadd..5847fc6 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -181,9 +181,7 @@ // If this node is ignored, notify from the platform parent if available, // since it will be unignored. BrowserAccessibility* target_node = - node->GetData().HasState(ax::mojom::State::kIgnored) - ? node->PlatformGetParent() - : node; + node->IsIgnored() ? node->PlatformGetParent() : node; if (target_node) { FireWinAccessibilityEvent(EVENT_OBJECT_REORDER, target_node); FireUiaStructureChangedEvent(StructureChangeType_ChildrenReordered, @@ -241,7 +239,7 @@ aria_properties_events_.insert(node); break; case ui::AXEventGenerator::Event::IGNORED_CHANGED: - if (node->HasState(ax::mojom::State::kIgnored)) { + if (node->IsIgnored()) { FireWinAccessibilityEvent(EVENT_OBJECT_HIDE, node); FireUiaStructureChangedEvent(StructureChangeType_ChildRemoved, node); } else { @@ -422,7 +420,7 @@ default: return; } - } else if (node->HasState(ax::mojom::State::kIgnored)) { + } else if (node->IsIgnored()) { return; } @@ -446,8 +444,7 @@ if (!ShouldFireEventForNode(node)) return; // Suppress events when |IGNORED_CHANGED| - if (node->HasState(ax::mojom::State::kIgnored) || - base::Contains(ignored_changed_nodes_, node)) + if (node->IsIgnored() || base::Contains(ignored_changed_nodes_, node)) return; ::UiaRaiseAutomationEvent(ToBrowserAccessibilityWin(node)->GetCOM(), @@ -461,12 +458,10 @@ return; if (!ShouldFireEventForNode(node)) return; - // Suppress events when |IGNORED_CHANGED| with the exception for firing // UIA_AriaPropertiesPropertyId-hidden event on non-text node marked as // ignored. - if (node->HasState(ax::mojom::State::kIgnored) || - base::Contains(ignored_changed_nodes_, node)) { + if (node->IsIgnored() || base::Contains(ignored_changed_nodes_, node)) { if (uia_property != UIA_AriaPropertiesPropertyId || node->IsTextOnlyObject()) return; @@ -501,7 +496,7 @@ default: return; } - } else if (node->HasState(ax::mojom::State::kIgnored)) { + } else if (node->IsIgnored()) { return; }
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index 2ee58a4f..12a7cf2 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -649,7 +649,7 @@ static size_t ActualUnignoredChildCount(const ui::AXNode* node) { size_t count = 0; for (const ui::AXNode* child : node->children()) { - if (child->data().HasState(ax::mojom::State::kIgnored)) { + if (child->IsIgnored()) { count += ActualUnignoredChildCount(child); } else { ++count; @@ -678,7 +678,7 @@ if (node->GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag, &tag)) base_message << ", node_tag: <" << tag.c_str() << ">"; - if (node->GetData().HasState(ax::mojom::State::kIgnored)) + if (node->IsIgnored()) base_message << ", IGNORED"; if (BrowserAccessibilityManager* manager = node->manager()) { if (ui::AXTree* tree = manager->ax_tree()) {
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 23798cdb..46807ac 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -3104,7 +3104,7 @@ base::nullopt /* appcache_host_id */, mojom::WasActivatedOption::kUnknown, base::UnguessableToken::Create() /* navigation_token */, - std::vector<PrefetchedSignedExchangeInfo>(), + std::vector<mojom::PrefetchedSignedExchangeInfoPtr>(), #if defined(OS_ANDROID) std::string(), /* data_url_as_string */ #endif
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 6d57d65..4a1f737 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -733,7 +733,7 @@ should_clear_history_list(), mojom::NavigationTiming::New(), base::nullopt, mojom::WasActivatedOption::kUnknown, base::UnguessableToken::Create(), - std::vector<PrefetchedSignedExchangeInfo>(), + std::vector<mojom::PrefetchedSignedExchangeInfoPtr>(), #if defined(OS_ANDROID) std::string(), #endif
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 76341f9..c7a2820 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -52,6 +52,7 @@ #include "content/common/content_constants_internal.h" #include "content/common/frame_messages.h" #include "content/common/navigation_params.h" +#include "content/common/navigation_params_mojom_traits.h" #include "content/common/navigation_params_utils.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" @@ -628,7 +629,8 @@ mojom::WasActivatedOption::kUnknown, base::UnguessableToken::Create(), // navigation_token std::vector< - PrefetchedSignedExchangeInfo>(), // prefetched_signed_exchanges + mojom:: + PrefetchedSignedExchangeInfoPtr>(), // prefetched_signed_exchanges #if defined(OS_ANDROID) std::string(), // data_url_as_string #endif @@ -699,7 +701,7 @@ mojom::NavigationTiming::New(), base::nullopt /* appcache_host_id; */, mojom::WasActivatedOption::kUnknown, base::UnguessableToken::Create() /* navigation_token */, - std::vector<PrefetchedSignedExchangeInfo>(), + std::vector<mojom::PrefetchedSignedExchangeInfoPtr>(), #if defined(OS_ANDROID) std::string(), /* data_url_as_string */ #endif @@ -2184,17 +2186,19 @@ render_frame_host_->GetProcess()->GetID(), render_frame_host_->GetRoutingID(), &service_worker_provider_info); } + auto common_params = common_params_.Clone(); + auto commit_params = commit_params_.Clone(); if (subresource_loader_params_ && !subresource_loader_params_->prefetched_signed_exchanges.empty()) { - commit_params_->prefetched_signed_exchanges = + commit_params->prefetched_signed_exchanges = std::move(subresource_loader_params_->prefetched_signed_exchanges); } render_frame_host_->CommitNavigation( - this, *common_params_, *commit_params_, response_head_.get(), - std::move(response_body_), std::move(url_loader_client_endpoints_), - is_view_source_, std::move(subresource_loader_params_), - std::move(subresource_overrides_), + this, std::move(common_params), std::move(commit_params), + response_head_.get(), std::move(response_body_), + std::move(url_loader_client_endpoints_), is_view_source_, + std::move(subresource_loader_params_), std::move(subresource_overrides_), std::move(service_worker_provider_info), devtools_navigation_token_, std::move(bundled_exchanges_handle_));
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 904a7f61..28ddfd0 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -125,6 +125,7 @@ #include "content/common/input/input_handler.mojom.h" #include "content/common/inter_process_time_ticks_converter.h" #include "content/common/navigation_params.h" +#include "content/common/navigation_params_mojom_traits.h" #include "content/common/navigation_params_utils.h" #include "content/common/render_message_filter.mojom.h" #include "content/common/renderer.mojom.h" @@ -4444,7 +4445,7 @@ NavigationDownloadPolicy download_policy; download_policy.SetDisallowed(NavigationDownloadType::kInterstitial); - mojom::CommonNavigationParams common_params( + auto common_params = mojom::CommonNavigationParams::New( data_url, base::nullopt, blink::mojom::Referrer::New(), ui::PAGE_TRANSITION_LINK, mojom::NavigationType::DIFFERENT_DOCUMENT, download_policy, false, GURL(), GURL(), PREVIEWS_OFF, @@ -4452,16 +4453,14 @@ false /* started_from_context_menu */, false /* has_user_gesture */, InitiatorCSPInfo(), std::vector<int>(), std::string(), false /* is_history_navigation_in_new_child_frame */, base::TimeTicks()); - mojom::CommitNavigationParams commit_params; - commit_params.navigation_token = base::UnguessableToken::Create(); - commit_params.navigation_timing = mojom::NavigationTiming::New(); - CommitNavigation( - nullptr /* navigation_request */, common_params, commit_params, - nullptr /* response_head */, mojo::ScopedDataPipeConsumerHandle(), - network::mojom::URLLoaderClientEndpointsPtr(), false, base::nullopt, - base::nullopt /* subresource_overrides */, nullptr /* provider_info */, - base::UnguessableToken::Create() /* not traced */, - nullptr /* bundled_exchanges_factory */); + CommitNavigation(nullptr /* navigation_request */, std::move(common_params), + CreateCommitNavigationParams(), nullptr /* response_head */, + mojo::ScopedDataPipeConsumerHandle(), + network::mojom::URLLoaderClientEndpointsPtr(), false, + base::nullopt, base::nullopt /* subresource_overrides */, + nullptr /* provider_info */, + base::UnguessableToken::Create() /* not traced */, + nullptr /* bundled_exchanges_factory */); } void RenderFrameHostImpl::Stop() { @@ -4804,8 +4803,8 @@ void RenderFrameHostImpl::CommitNavigation( NavigationRequest* navigation_request, - const mojom::CommonNavigationParams& common_params, - const mojom::CommitNavigationParams& commit_params, + mojom::CommonNavigationParamsPtr common_params, + mojom::CommitNavigationParamsPtr commit_params, network::ResourceResponse* response_head, mojo::ScopedDataPipeConsumerHandle response_body, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, @@ -4820,8 +4819,8 @@ TRACE_EVENT2("navigation", "RenderFrameHostImpl::CommitNavigation", "frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url", - common_params.url.possibly_invalid_spec()); - DCHECK(!IsRendererDebugURL(common_params.url)); + common_params->url.possibly_invalid_spec()); + DCHECK(!IsRendererDebugURL(common_params->url)); bool is_mhtml_iframe = navigation_request && navigation_request->IsForMhtmlSubframe(); @@ -4829,9 +4828,9 @@ // A |response| and a |url_loader_client_endpoints| must always be provided, // except for edge cases, where another way to load the document exist. DCHECK((response_head && url_loader_client_endpoints) || - common_params.url.SchemeIs(url::kDataScheme) || - NavigationTypeUtils::IsSameDocument(common_params.navigation_type) || - !IsURLHandledByNetworkStack(common_params.url) || is_mhtml_iframe); + common_params->url.SchemeIs(url::kDataScheme) || + NavigationTypeUtils::IsSameDocument(common_params->navigation_type) || + !IsURLHandledByNetworkStack(common_params->url) || is_mhtml_iframe); // All children of MHTML documents must be MHTML documents. // As a defensive measure, crash the browser if something went wrong. @@ -4839,7 +4838,7 @@ RenderFrameHostImpl* root = frame_tree_node()->frame_tree()->root()->current_frame_host(); if (root->is_mhtml_document_ && - !common_params.url.SchemeIs(url::kDataScheme)) { + !common_params->url.SchemeIs(url::kDataScheme)) { bool loaded_from_outside_the_archive = response_head || url_loader_client_endpoints; CHECK(!loaded_from_outside_the_archive); @@ -4856,10 +4855,10 @@ // // TODO(arthursonzogni): Replace DumpWithoutCrashing by a CHECK on M79 if it // is never reached. - bool is_srcdoc = common_params.url.IsAboutSrcdoc(); + bool is_srcdoc = common_params->url.IsAboutSrcdoc(); if (is_srcdoc) { if (frame_tree_node_->IsMainFrame() || - common_params.url != GURL(url::kAboutSrcdocURL)) { + common_params->url != GURL(url::kAboutSrcdocURL)) { base::debug::DumpWithoutCrashing(); } } @@ -4871,9 +4870,9 @@ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); const GURL& lock_url = GetSiteInstance()->lock_url(); if (lock_url != GURL(kUnreachableWebDataURL) && - common_params.url.IsStandard() && + common_params->url.IsStandard() && !policy->CanAccessDataForOrigin(GetProcess()->GetID(), - common_params.url) && + common_params->url) && !is_mhtml_iframe) { base::debug::SetCrashKeyString( base::debug::AllocateCrashKeyString("lock_url", @@ -4882,20 +4881,20 @@ base::debug::SetCrashKeyString( base::debug::AllocateCrashKeyString("commit_origin", base::debug::CrashKeySize::Size64), - common_params.url.GetOrigin().spec()); + common_params->url.GetOrigin().spec()); base::debug::SetCrashKeyString( base::debug::AllocateCrashKeyString("is_main_frame", base::debug::CrashKeySize::Size32), frame_tree_node_->IsMainFrame() ? "true" : "false"); NOTREACHED() << "Commiting in incompatible process for URL: " << lock_url - << " lock vs " << common_params.url.GetOrigin(); + << " lock vs " << common_params->url.GetOrigin(); base::debug::DumpWithoutCrashing(); } const bool is_first_navigation = !has_committed_any_navigation_; has_committed_any_navigation_ = true; - UpdatePermissionsForNavigation(common_params, commit_params); + UpdatePermissionsForNavigation(*common_params, *commit_params); // Get back to a clean state, in case we start a new navigation without // completing an unload handler. @@ -4911,20 +4910,20 @@ const network::ResourceResponseHead head = response_head ? response_head->head : network::ResourceResponseHead(); const bool is_same_document = - NavigationTypeUtils::IsSameDocument(common_params.navigation_type); + NavigationTypeUtils::IsSameDocument(common_params->navigation_type); // Network isolation key should be filled before the URLLoaderFactory for // sub-resources is created. Only update for cross document navigations since // for opaque origin same document navigations, a new origin should not be // created as that would be different from the original. // TODO(crbug.com/971796): For about:blank and other such urls, - // common_params.url currently leads to an opaque origin to be created. Once + // common_params->url currently leads to an opaque origin to be created. Once // this is fixed, the origin which these navigations eventually get committed // to will be available here as well. // TODO(crbug.com/979296): Consider changing this code to copy an origin // instead of creating one from a URL which lacks opacity information. if (!is_same_document) { - const url::Origin frame_origin = url::Origin::Create(common_params.url); + const url::Origin frame_origin = url::Origin::Create(common_params->url); const url::Origin top_frame_origin = frame_tree_node_->IsMainFrame() ? frame_origin : frame_tree_->root()->current_origin(); @@ -4979,7 +4978,7 @@ pending_default_factory; // See if this is for WebUI. - std::string scheme = common_params.url.scheme(); + std::string scheme = common_params->url.scheme(); const auto& webui_schemes = URLDataManagerBackend::GetWebUISchemes(); if (base::Contains(webui_schemes, scheme)) { network::mojom::URLLoaderFactoryPtr factory_for_webui = @@ -4990,7 +4989,7 @@ // of WebUIs that need to be fixed to not make network requests in JS. if ((enabled_bindings_ & kWebUIBindingsPolicyMask) && !GetContentClient()->browser()->IsWebUIAllowedToMakeNetworkRequests( - url::Origin::Create(common_params.url.GetOrigin()))) { + url::Origin::Create(common_params->url.GetOrigin()))) { pending_default_factory = factory_for_webui.PassInterface(); // WebUIURLLoaderFactory will kill the renderer if it sees a request // with a non-chrome scheme. Register a URLLoaderFactory for the about @@ -5035,7 +5034,7 @@ // Other URLs like about:srcdoc or about:blank might be able load files, but // only because they will inherit loaders from their parents instead of the // ones provided by the browser process here. - if (common_params.url.SchemeIsFile()) { + if (common_params->url.SchemeIsFile()) { auto file_factory = std::make_unique<FileURLLoaderFactory>( browser_context->GetPath(), browser_context->GetSharedCorsOriginAccessList(), @@ -5046,7 +5045,7 @@ } #if defined(OS_ANDROID) - if (common_params.url.SchemeIs(url::kContentScheme)) { + if (common_params->url.SchemeIs(url::kContentScheme)) { // Only content:// URLs can load content:// subresources auto content_factory = std::make_unique<ContentURLLoaderFactory>( base::CreateSequencedTaskRunner( @@ -5114,14 +5113,16 @@ subresource_loader_factories); if (is_same_document) { + bool should_replace_current_entry = + common_params->should_replace_current_entry; DCHECK(same_document_navigation_request_); GetNavigationControl()->CommitSameDocumentNavigation( - common_params.Clone(), commit_params.Clone(), + std::move(common_params), std::move(commit_params), base::BindOnce(&RenderFrameHostImpl::OnSameDocumentCommitProcessed, base::Unretained(this), same_document_navigation_request_->navigation_handle() ->GetNavigationId(), - common_params.should_replace_current_entry)); + should_replace_current_entry)); } else { // Pass the controller service worker info if we have one. blink::mojom::ControllerServiceWorkerInfoPtr controller; @@ -5222,9 +5223,13 @@ DCHECK(!prefetch_loader_factory); } + // If a network request was made, update the Previews state. + if (IsURLHandledByNetworkStack(common_params->url)) + last_navigation_previews_state_ = common_params->previews_state; + SendCommitNavigation( - navigation_client, navigation_request, common_params.Clone(), - commit_params.Clone(), head, std::move(response_body), + navigation_client, navigation_request, std::move(common_params), + std::move(commit_params), head, std::move(response_body), std::move(url_loader_client_endpoints), std::move(subresource_loader_factories), std::move(subresource_overrides), std::move(controller), @@ -5242,10 +5247,6 @@ subresource_loader_params->controller_service_worker_object_host, std::move(remote_object), sent_state)); } - - // If a network request was made, update the Previews state. - if (IsURLHandledByNetworkStack(common_params.url)) - last_navigation_previews_state_ = common_params.previews_state; } is_loading_ = true;
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index b877b7ba..916f673 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -690,8 +690,8 @@ // process, e.g. by AppCache etc. void CommitNavigation( NavigationRequest* navigation_request, - const mojom::CommonNavigationParams& common_params, - const mojom::CommitNavigationParams& commit_params, + mojom::CommonNavigationParamsPtr common_params, + mojom::CommitNavigationParamsPtr commit_params, network::ResourceResponse* response_head, mojo::ScopedDataPipeConsumerHandle response_body, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
diff --git a/content/browser/indexed_db/indexed_db_leveldb_coding.cc b/content/browser/indexed_db/indexed_db_leveldb_coding.cc index 76a5a5f..c2dd756 100644 --- a/content/browser/indexed_db/indexed_db_leveldb_coding.cc +++ b/content/browser/indexed_db/indexed_db_leveldb_coding.cc
@@ -204,7 +204,7 @@ EncodeDouble(value.number(), into); DCHECK_EQ(9u, static_cast<size_t>(into->size() - previous_size)); return; - case blink::mojom::IDBKeyType::Null: + case blink::mojom::IDBKeyType::None: case blink::mojom::IDBKeyType::Invalid: case blink::mojom::IDBKeyType::Min: default:
diff --git a/content/browser/navigation_subresource_loader_params.h b/content/browser/navigation_subresource_loader_params.h index 6eb1951..0cc3345 100644 --- a/content/browser/navigation_subresource_loader_params.h +++ b/content/browser/navigation_subresource_loader_params.h
@@ -7,7 +7,7 @@ #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" -#include "content/common/prefetched_signed_exchange_info.h" +#include "content/common/prefetched_signed_exchange_info.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom.h" @@ -50,7 +50,8 @@ // navigation was served from the cache, |prefetched_signed_exchanges| // contains the all prefetched signed exchanges and they will be passed to the // renderer. - std::vector<PrefetchedSignedExchangeInfo> prefetched_signed_exchanges; + std::vector<mojom::PrefetchedSignedExchangeInfoPtr> + prefetched_signed_exchanges; }; } // namespace content
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 0d15fe7..27e6b1fd 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -131,6 +131,7 @@ #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/site_instance_impl.h" #include "content/browser/storage_partition_impl.h" +#include "content/browser/theme_helper.h" #include "content/browser/tracing/background_tracing_manager_impl.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/child_process.mojom.h" @@ -4421,6 +4422,9 @@ GetRendererInterface()->EnableV8LowMemoryMode(); } + // Send the initial system color info to the renderer. + ThemeHelper::GetInstance()->SendSystemColorInfo(GetRendererInterface()); + // NOTE: This needs to be before flushing queued messages, because // ExtensionService uses this notification to initialize the renderer process // with state that must be there before any JavaScript executes.
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc index 4722a62..f540cadf 100644 --- a/content/browser/service_worker/embedded_worker_test_helper.cc +++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -77,6 +77,10 @@ const std::string& highlight_color) override { NOTREACHED(); } + void UpdateSystemColorInfo( + mojom::UpdateSystemColorInfoParamsPtr params) override { + NOTREACHED(); + } void PurgePluginListCache(bool reload_pages) override { NOTREACHED(); } void SetProcessState(mojom::RenderProcessState process_state) override { NOTREACHED();
diff --git a/content/browser/sms/sms_browsertest.cc b/content/browser/sms/sms_browsertest.cc index ff0c513..bb2e13a 100644 --- a/content/browser/sms/sms_browsertest.cc +++ b/content/browser/sms/sms_browsertest.cc
@@ -3,11 +3,11 @@ // found in the LICENSE file. #include "content/browser/browser_main_loop.h" -#include "content/browser/sms/sms_provider.h" #include "content/browser/sms/sms_service.h" +#include "content/browser/sms/test/mock_sms_dialog.h" +#include "content/browser/sms/test/mock_sms_provider.h" +#include "content/browser/sms/test/mock_sms_web_contents_delegate.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/sms_dialog.h" -#include "content/public/browser/web_contents_delegate.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" @@ -29,42 +29,6 @@ namespace { -class MockSmsDialog : public SmsDialog { - public: - MockSmsDialog() : SmsDialog() {} - ~MockSmsDialog() override = default; - - MOCK_METHOD3(Open, - void(RenderFrameHost*, base::OnceClosure, base::OnceClosure)); - MOCK_METHOD0(Close, void()); - MOCK_METHOD0(SmsReceived, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockSmsDialog); -}; - -class MockWebContentsDelegate : public WebContentsDelegate { - public: - MockWebContentsDelegate() = default; - ~MockWebContentsDelegate() override = default; - - MOCK_METHOD0(CreateSmsDialog, std::unique_ptr<SmsDialog>()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate); -}; - -class MockSmsProvider : public SmsProvider { - public: - MockSmsProvider() = default; - ~MockSmsProvider() override = default; - - MOCK_METHOD0(Retrieve, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockSmsProvider); -}; - class SmsBrowserTest : public ContentBrowserTest { public: SmsBrowserTest() = default; @@ -92,7 +56,7 @@ cert_verifier_.TearDownInProcessBrowserTestFixture(); } - NiceMock<MockWebContentsDelegate> delegate_; + NiceMock<MockSmsWebContentsDelegate> delegate_; // Similar to net::MockCertVerifier, but also updates the CertVerifier // used by the NetworkService. ContentMockCertVerifier cert_verifier_; @@ -474,7 +438,7 @@ BrowserMainLoop::GetInstance()->SetSmsProviderForTesting( base::WrapUnique(provider)); - StrictMock<MockWebContentsDelegate> delegate; + StrictMock<MockSmsWebContentsDelegate> delegate; shell()->web_contents()->SetDelegate(&delegate); auto* dialog = new StrictMock<MockSmsDialog>();
diff --git a/content/browser/sms/sms_parser.cc b/content/browser/sms/sms_parser.cc index 156d24e..68d85ef 100644 --- a/content/browser/sms/sms_parser.cc +++ b/content/browser/sms/sms_parser.cc
@@ -9,6 +9,7 @@ #include "content/browser/sms/sms_parser.h" #include "base/optional.h" +#include "net/base/url_util.h" #include "url/gurl.h" #include "url/origin.h" @@ -28,7 +29,11 @@ GURL gurl(url); - if (!gurl.is_valid() || !gurl.SchemeIs(url::kHttpsScheme)) { + if (!gurl.is_valid()) { + return base::nullopt; + } + + if (!(gurl.SchemeIs(url::kHttpsScheme) || net::IsLocalhost(gurl))) { return base::nullopt; }
diff --git a/content/browser/sms/sms_parser_unittest.cc b/content/browser/sms/sms_parser_unittest.cc index e8e811a..fa0f443 100644 --- a/content/browser/sms/sms_parser_unittest.cc +++ b/content/browser/sms/sms_parser_unittest.cc
@@ -55,6 +55,16 @@ ASSERT_EQ(origin, url::Origin::Create(url)); } +TEST(SmsParserTest, LocalhostForDevelopment) { + ASSERT_EQ(SmsParser::Parse("For: http://localhost:8080"), + url::Origin::Create(GURL("http://localhost:8080"))); + ASSERT_EQ(SmsParser::Parse("For: http://localhost:80"), + url::Origin::Create(GURL("http://localhost:80"))); + ASSERT_EQ(SmsParser::Parse("For: http://localhost"), + url::Origin::Create(GURL("http://localhost"))); + ASSERT_FALSE(SmsParser::Parse("For: localhost")); +} + TEST(SmsParserTest, Paths) { base::Optional<url::Origin> origin = SmsParser::Parse("For: https://example.com/foobar"); @@ -177,6 +187,10 @@ } } +TEST(SmsParserTest, HarmlessOriginsButInvalid) { + ASSERT_FALSE(SmsParser::Parse("For: data://123")); +} + TEST(SmsParserTest, AppHash) { base::Optional<url::Origin> origin = SmsParser::Parse("<#> Hello World\nFor: https://example.com?s3LhKBB0M33");
diff --git a/content/browser/sms/sms_service_unittest.cc b/content/browser/sms/sms_service_unittest.cc index 7a552dbf..2a81cebe 100644 --- a/content/browser/sms/sms_service_unittest.cc +++ b/content/browser/sms/sms_service_unittest.cc
@@ -14,9 +14,10 @@ #include "base/test/bind_test_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/time/time.h" -#include "content/browser/sms/sms_provider.h" +#include "content/browser/sms/test/mock_sms_dialog.h" +#include "content/browser/sms/test/mock_sms_provider.h" +#include "content/browser/sms/test/mock_sms_web_contents_delegate.h" #include "content/browser/web_contents/web_contents_impl.h" -#include "content/public/browser/web_contents_delegate.h" #include "content/public/common/service_manager_connection.h" #include "content/public/test/navigation_simulator.h" #include "content/public/test/test_browser_context.h" @@ -49,51 +50,10 @@ class RenderFrameHost; -using blink::mojom::SmsReceiverPtr; -using ::testing::_; -using ::testing::Invoke; -using ::testing::NiceMock; - namespace { const char kTestUrl[] = "https://www.google.com"; -class MockSmsProvider : public SmsProvider { - public: - MockSmsProvider() = default; - ~MockSmsProvider() override = default; - - MOCK_METHOD0(Retrieve, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockSmsProvider); -}; - -class MockSmsDialog : public SmsDialog { - public: - MockSmsDialog() : SmsDialog() {} - ~MockSmsDialog() override = default; - - MOCK_METHOD3(Open, - void(RenderFrameHost*, base::OnceClosure, base::OnceClosure)); - MOCK_METHOD0(Close, void()); - MOCK_METHOD0(SmsReceived, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockSmsDialog); -}; - -class MockWebContentsDelegate : public WebContentsDelegate { - public: - MockWebContentsDelegate() = default; - ~MockWebContentsDelegate() override = default; - - MOCK_METHOD0(CreateSmsDialog, std::unique_ptr<SmsDialog>()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate); -}; - // Service encapsulates a SmsService endpoint, with all of its dependencies // mocked out (and the common plumbing needed to inject them), and a // SmsReceiverPtr endpoint that tests can use to make requests. @@ -115,9 +75,8 @@ : Service(web_contents, web_contents->GetMainFrame()->GetLastCommittedOrigin()) {} - NiceMock<MockWebContentsDelegate>* delegate() { return &delegate_; } + NiceMock<MockSmsWebContentsDelegate>* delegate() { return &delegate_; } NiceMock<MockSmsProvider>* provider() { return &provider_; } - blink::mojom::SmsReceiverPtr* client() { return &service_ptr_; } void SetupSmsDialog(content::RenderFrameHost* rfh) { auto* dialog = new NiceMock<MockSmsDialog>(); @@ -150,7 +109,7 @@ } private: - NiceMock<MockWebContentsDelegate> delegate_; + NiceMock<MockSmsWebContentsDelegate> delegate_; NiceMock<MockSmsProvider> provider_; blink::mojom::SmsReceiverPtr service_ptr_; std::unique_ptr<SmsService> service_; @@ -397,7 +356,7 @@ TEST_F(SmsServiceTest, CleansUp) { NavigateAndCommit(GURL(kTestUrl)); - NiceMock<MockWebContentsDelegate> delegate; + NiceMock<MockSmsWebContentsDelegate> delegate; WebContentsImpl* web_contents_impl = reinterpret_cast<WebContentsImpl*>(web_contents()); web_contents_impl->SetDelegate(&delegate);
diff --git a/content/browser/sms/test/mock_sms_dialog.cc b/content/browser/sms/test/mock_sms_dialog.cc new file mode 100644 index 0000000..a49b250 --- /dev/null +++ b/content/browser/sms/test/mock_sms_dialog.cc
@@ -0,0 +1,13 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/sms/test/mock_sms_dialog.h" + +namespace content { + +MockSmsDialog::MockSmsDialog() : SmsDialog() {} + +MockSmsDialog::~MockSmsDialog() = default; + +} // namespace content
diff --git a/content/browser/sms/test/mock_sms_dialog.h b/content/browser/sms/test/mock_sms_dialog.h new file mode 100644 index 0000000..8daf897 --- /dev/null +++ b/content/browser/sms/test/mock_sms_dialog.h
@@ -0,0 +1,30 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SMS_TEST_MOCK_SMS_DIALOG_H_ +#define CONTENT_BROWSER_SMS_TEST_MOCK_SMS_DIALOG_H_ + +#include "base/macros.h" +#include "content/public/browser/sms_dialog.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace content { + +class MockSmsDialog : public SmsDialog { + public: + MockSmsDialog(); + ~MockSmsDialog() override; + + MOCK_METHOD3(Open, + void(RenderFrameHost*, base::OnceClosure, base::OnceClosure)); + MOCK_METHOD0(Close, void()); + MOCK_METHOD0(SmsReceived, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSmsDialog); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SMS_TEST_MOCK_SMS_DIALOG_H_
diff --git a/content/browser/sms/test/mock_sms_provider.cc b/content/browser/sms/test/mock_sms_provider.cc new file mode 100644 index 0000000..0e7c8305 --- /dev/null +++ b/content/browser/sms/test/mock_sms_provider.cc
@@ -0,0 +1,13 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/sms/test/mock_sms_provider.h" + +namespace content { + +MockSmsProvider::MockSmsProvider() = default; + +MockSmsProvider::~MockSmsProvider() = default; + +} // namespace content
diff --git a/content/browser/sms/test/mock_sms_provider.h b/content/browser/sms/test/mock_sms_provider.h new file mode 100644 index 0000000..986222d --- /dev/null +++ b/content/browser/sms/test/mock_sms_provider.h
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SMS_TEST_MOCK_SMS_PROVIDER_H_ +#define CONTENT_BROWSER_SMS_TEST_MOCK_SMS_PROVIDER_H_ + +#include "base/macros.h" +#include "content/browser/sms/sms_provider.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace content { + +class MockSmsProvider : public SmsProvider { + public: + MockSmsProvider(); + ~MockSmsProvider() override; + + MOCK_METHOD0(Retrieve, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSmsProvider); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SMS_TEST_MOCK_SMS_PROVIDER_H_
diff --git a/content/browser/sms/test/mock_sms_web_contents_delegate.cc b/content/browser/sms/test/mock_sms_web_contents_delegate.cc new file mode 100644 index 0000000..e1453346 --- /dev/null +++ b/content/browser/sms/test/mock_sms_web_contents_delegate.cc
@@ -0,0 +1,13 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/sms/test/mock_sms_web_contents_delegate.h" + +namespace content { + +MockSmsWebContentsDelegate::MockSmsWebContentsDelegate() = default; + +MockSmsWebContentsDelegate::~MockSmsWebContentsDelegate() = default; + +} // namespace content
diff --git a/content/browser/sms/test/mock_sms_web_contents_delegate.h b/content/browser/sms/test/mock_sms_web_contents_delegate.h new file mode 100644 index 0000000..33d1812b --- /dev/null +++ b/content/browser/sms/test/mock_sms_web_contents_delegate.h
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SMS_TEST_MOCK_SMS_WEB_CONTENTS_DELEGATE_H_ +#define CONTENT_BROWSER_SMS_TEST_MOCK_SMS_WEB_CONTENTS_DELEGATE_H_ + +#include "base/macros.h" +#include "content/public/browser/sms_dialog.h" +#include "content/public/browser/web_contents_delegate.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace content { + +class MockSmsWebContentsDelegate : public WebContentsDelegate { + public: + MockSmsWebContentsDelegate(); + ~MockSmsWebContentsDelegate() override; + + MOCK_METHOD0(CreateSmsDialog, std::unique_ptr<SmsDialog>()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSmsWebContentsDelegate); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SMS_TEST_MOCK_SMS_WEB_CONTENTS_DELEGATE_H_
diff --git a/content/browser/theme_helper.cc b/content/browser/theme_helper.cc new file mode 100644 index 0000000..817f085 --- /dev/null +++ b/content/browser/theme_helper.cc
@@ -0,0 +1,57 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/theme_helper.h" + +#include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/common/renderer.mojom.h" + +namespace content { + +// static +ThemeHelper* ThemeHelper::GetInstance() { + static base::NoDestructor<ThemeHelper> s_theme_helper; + return s_theme_helper.get(); +} + +ThemeHelper::ThemeHelper() : theme_observer_(this) { + theme_observer_.Add(ui::NativeTheme::GetInstanceForWeb()); +} + +ThemeHelper::~ThemeHelper() {} + +mojom::UpdateSystemColorInfoParamsPtr MakeUpdateSystemColorInfoParams( + ui::NativeTheme* native_theme) { + mojom::UpdateSystemColorInfoParamsPtr params = + mojom::UpdateSystemColorInfoParams::New(); + params->is_dark_mode = native_theme->ShouldUseDarkColors(); + params->is_high_contrast = native_theme->UsesHighContrastColors(); + params->preferred_color_scheme = native_theme->GetPreferredColorScheme(); + const auto& colors = native_theme->GetSystemColors(); + params->colors.insert(colors.begin(), colors.end()); + + return params; +} + +void ThemeHelper::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) { + DCHECK(theme_observer_.IsObserving(observed_theme)); + + mojom::UpdateSystemColorInfoParamsPtr params = + MakeUpdateSystemColorInfoParams(observed_theme); + for (auto iter = RenderProcessHost::AllHostsIterator(); !iter.IsAtEnd(); + iter.Advance()) { + if (iter.GetCurrentValue()->IsInitializedAndNotDead()) { + iter.GetCurrentValue()->GetRendererInterface()->UpdateSystemColorInfo( + params->Clone()); + } + } +} + +void ThemeHelper::SendSystemColorInfo(mojom::Renderer* renderer) const { + mojom::UpdateSystemColorInfoParamsPtr params = + MakeUpdateSystemColorInfoParams(ui::NativeTheme::GetInstanceForWeb()); + renderer->UpdateSystemColorInfo(std::move(params)); +} + +} // namespace content
diff --git a/content/browser/theme_helper.h b/content/browser/theme_helper.h new file mode 100644 index 0000000..06fa6cc --- /dev/null +++ b/content/browser/theme_helper.h
@@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_THEME_HELPER_H_ +#define CONTENT_BROWSER_THEME_HELPER_H_ + +#include "base/macros.h" +#include "base/no_destructor.h" +#include "base/scoped_observer.h" +#include "content/common/renderer.mojom-forward.h" +#include "ui/native_theme/native_theme.h" +#include "ui/native_theme/native_theme_observer.h" + +namespace content { + +// This class is used to monitor system color info changes and to notify the +// renderer processes. +class ThemeHelper : public ui::NativeThemeObserver { + public: + static ThemeHelper* GetInstance(); + + void SendSystemColorInfo(mojom::Renderer* renderer) const; + + private: + friend class base::NoDestructor<ThemeHelper>; + ThemeHelper(); + ~ThemeHelper() override; + + // Overridden from ui::NativeThemeObserver: + void OnNativeThemeUpdated(ui::NativeTheme* updated_theme) override; + + ScopedObserver<ui::NativeTheme, ui::NativeThemeObserver> theme_observer_; + + DISALLOW_COPY_AND_ASSIGN(ThemeHelper); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_THEME_HELPER_H_ \ No newline at end of file
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc index ae7abdd..0c4d6b9 100644 --- a/content/browser/web_package/prefetched_signed_exchange_cache.cc +++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -378,7 +378,7 @@ public: PrefetchedNavigationLoaderInterceptor( std::unique_ptr<const PrefetchedSignedExchangeCache::Entry> exchange, - std::vector<PrefetchedSignedExchangeInfo> info_list) + std::vector<mojom::PrefetchedSignedExchangeInfoPtr> info_list) : exchange_(std::move(exchange)), info_list_(std::move(info_list)) {} ~PrefetchedNavigationLoaderInterceptor() override {} @@ -451,7 +451,7 @@ State state_ = State::kInitial; std::unique_ptr<const PrefetchedSignedExchangeCache::Entry> exchange_; - std::vector<PrefetchedSignedExchangeInfo> info_list_; + std::vector<mojom::PrefetchedSignedExchangeInfoPtr> info_list_; base::WeakPtrFactory<PrefetchedNavigationLoaderInterceptor> weak_factory_{ this}; @@ -700,7 +700,7 @@ headers_size_total); } -std::vector<PrefetchedSignedExchangeInfo> +std::vector<mojom::PrefetchedSignedExchangeInfoPtr> PrefetchedSignedExchangeCache::GetInfoListForNavigation( const Entry& main_exchange, const base::Time& now) { @@ -712,7 +712,7 @@ url::Origin::Create(main_exchange.inner_url()); const auto inner_url_header_integrity_map = GetAllowedAltSXG(main_exchange); - std::vector<PrefetchedSignedExchangeInfo> info_list; + std::vector<mojom::PrefetchedSignedExchangeInfoPtr> info_list; EntryMap::iterator exchanges_it = exchanges_.begin(); while (exchanges_it != exchanges_.end()) { const std::unique_ptr<const Entry>& exchange = exchanges_it->second; @@ -735,10 +735,10 @@ new SubresourceSignedExchangeURLLoaderFactory( mojo::MakeRequest(&loader_factory_info), exchange->Clone(), request_initiator_site_lock); - info_list.emplace_back( + info_list.emplace_back(mojom::PrefetchedSignedExchangeInfo::New( exchange->outer_url(), *exchange->header_integrity(), exchange->inner_url(), *exchange->inner_response(), - std::move(loader_factory_info).PassHandle().release()); + std::move(loader_factory_info).PassHandle())); } ++exchanges_it; }
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.h b/content/browser/web_package/prefetched_signed_exchange_cache.h index 41a5e0c..0887908 100644 --- a/content/browser/web_package/prefetched_signed_exchange_cache.h +++ b/content/browser/web_package/prefetched_signed_exchange_cache.h
@@ -10,7 +10,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "content/common/content_export.h" -#include "content/common/prefetched_signed_exchange_info.h" +#include "content/common/prefetched_signed_exchange_info.mojom.h" #include "net/base/hash_value.h" #include "services/network/public/cpp/resource_response.h" #include "services/network/public/cpp/url_loader_completion_status.h" @@ -122,7 +122,7 @@ // |main_exchange|'s inner response and which outer URL's origin is same as // the origin of |main_exchange|'s outer URL. Note that this method erases // expired entries in |exchanges_|. - std::vector<PrefetchedSignedExchangeInfo> GetInfoListForNavigation( + std::vector<mojom::PrefetchedSignedExchangeInfoPtr> GetInfoListForNavigation( const Entry& main_exchange, const base::Time& now);
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 51303db..53d4fcf 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -138,10 +138,10 @@ "input/input_event_ack.h", "input/input_event_ack_state.cc", "input/input_event_dispatch_type.h", - "input/input_event_stream_validator.cc", - "input/input_event_stream_validator.h", "input/input_event_mojom_traits.cc", "input/input_event_mojom_traits.h", + "input/input_event_stream_validator.cc", + "input/input_event_stream_validator.h", "input/input_param_traits.cc", "input/input_param_traits.h", "input/sync_compositor_messages.cc", @@ -187,6 +187,7 @@ "navigation_gesture.h", "navigation_params.cc", "navigation_params.h", + "navigation_params_mojom_traits.h", "navigation_params_utils.h", "net/record_load_histograms.cc", "net/record_load_histograms.h", @@ -201,8 +202,6 @@ "pepper_plugin_list.h", "pepper_renderer_instance_data.cc", "pepper_renderer_instance_data.h", - "prefetched_signed_exchange_info.cc", - "prefetched_signed_exchange_info.h", "process_type.cc", "render_widget_surface_properties.cc", "render_widget_surface_properties.h", @@ -330,6 +329,7 @@ "//ui/gl", "//ui/gl/init", "//ui/latency/ipc", + "//ui/native_theme", "//ui/shell_dialogs", "//url", "//url/ipc:url_ipc", @@ -480,6 +480,7 @@ "navigation_client.mojom", "navigation_params.mojom", "page_state.mojom", + "prefetched_signed_exchange_info.mojom", "render_frame_metadata.mojom", "render_message_filter.mojom", "renderer.mojom",
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 88cddca..d23817a8 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -466,14 +466,6 @@ IPC_STRUCT_TRAITS_MEMBER(initiator_self_source) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(content::PrefetchedSignedExchangeInfo) - IPC_STRUCT_TRAITS_MEMBER(outer_url) - IPC_STRUCT_TRAITS_MEMBER(header_integrity) - IPC_STRUCT_TRAITS_MEMBER(inner_url) - IPC_STRUCT_TRAITS_MEMBER(inner_response) - IPC_STRUCT_TRAITS_MEMBER(loader_factory_handle) -IPC_STRUCT_TRAITS_END() - IPC_STRUCT_TRAITS_BEGIN(blink::ParsedFeaturePolicyDeclaration) IPC_STRUCT_TRAITS_MEMBER(feature) IPC_STRUCT_TRAITS_MEMBER(values)
diff --git a/content/common/native_types.mojom b/content/common/native_types.mojom index a08d65b..445e9d1 100644 --- a/content/common/native_types.mojom +++ b/content/common/native_types.mojom
@@ -96,3 +96,9 @@ [Native] enum TouchAction; + +[Native] +enum PreferredColorScheme; + +[Native] +enum SystemThemeColor;
diff --git a/content/common/native_types.typemap b/content/common/native_types.typemap index bef49a4f..19d80b6 100644 --- a/content/common/native_types.typemap +++ b/content/common/native_types.typemap
@@ -29,6 +29,7 @@ "//ui/events/blink/did_overscroll_params.h", "//ui/events/blink/web_input_event_traits.h", "//ui/latency/ipc/latency_info_param_traits.h", + "//ui/native_theme/native_theme.h", ] traits_headers = [ "//content/common/frame_messages.h", @@ -78,7 +79,9 @@ "content.mojom.NetworkConnectionType=net::NetworkChangeNotifier::ConnectionType", "content.mojom.DidOverscrollParams=ui::DidOverscrollParams", "content.mojom.PointerType=blink::WebPointerProperties::PointerType", + "content.mojom.PreferredColorScheme=ui::NativeTheme::PreferredColorScheme", "content.mojom.VisualProperties=content::VisualProperties", + "content.mojom.SystemThemeColor=ui::NativeTheme::SystemThemeColor", "content.mojom.SyntheticSmoothDrag=content::SyntheticSmoothDragGestureParams", "content.mojom.SyntheticSmoothScroll=content::SyntheticSmoothScrollGestureParams", "content.mojom.SyntheticPinch=content::SyntheticPinchGestureParams",
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index 6c89ffb..9775680e 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -20,7 +20,7 @@ #include "content/common/content_security_policy/content_security_policy.h" #include "content/common/content_security_policy/csp_disposition_enum.h" #include "content/common/navigation_params.mojom-forward.h" -#include "content/common/prefetched_signed_exchange_info.h" +#include "content/common/prefetched_signed_exchange_info.mojom.h" #include "content/public/common/navigation_policy.h" #include "content/public/common/page_state.h" #include "content/public/common/previews_state.h"
diff --git a/content/common/navigation_params.mojom b/content/common/navigation_params.mojom index c0016a2d..bdcc940 100644 --- a/content/common/navigation_params.mojom +++ b/content/common/navigation_params.mojom
@@ -4,6 +4,7 @@ module content.mojom; +import "content/common/prefetched_signed_exchange_info.mojom"; import "content/public/common/was_activated_option.mojom"; import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; @@ -14,7 +15,6 @@ import "url/mojom/origin.mojom"; import "url/mojom/url.mojom"; - [Native] struct InitiatorCSPInfo; @@ -31,9 +31,6 @@ enum PageTransition; [Native] -struct PrefetchedSignedExchangeInfo; - -[Native] struct SourceLocation; enum NavigationType {
diff --git a/content/common/navigation_params.typemap b/content/common/navigation_params.typemap index c3ab177..3067bad 100644 --- a/content/common/navigation_params.typemap +++ b/content/common/navigation_params.typemap
@@ -4,8 +4,8 @@ mojom = "//content/common/navigation_params.mojom" public_headers = [ + "//content/common/content_param_traits.h", "//content/common/navigation_params.h", - "//content/common/prefetched_signed_exchange_info.h", "//content/public/common/page_state.h", "//content/public/common/navigation_policy.h", "//third_party/blink/public/platform/web_mixed_content_context_type.h", @@ -24,6 +24,6 @@ "content.mojom.NavigationDownloadPolicy=::content::NavigationDownloadPolicy", "content.mojom.PageState=::content::PageState", "content.mojom.PageTransition=::ui::PageTransition", - "content.mojom.PrefetchedSignedExchangeInfo=::content::PrefetchedSignedExchangeInfo", + "content.mojom.SHA256HashValue=::net::SHA256HashValue", "content.mojom.SourceLocation=::content::SourceLocation", ]
diff --git a/content/common/navigation_params_mojom_traits.h b/content/common/navigation_params_mojom_traits.h new file mode 100644 index 0000000..b08f7758d --- /dev/null +++ b/content/common/navigation_params_mojom_traits.h
@@ -0,0 +1,26 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_NAVIGATION_PARAMS_MOJOM_TRAITS_H_ +#define CONTENT_COMMON_NAVIGATION_PARAMS_MOJOM_TRAITS_H_ + +#include "content/common/prefetched_signed_exchange_info.mojom.h" +#include "mojo/public/cpp/bindings/clone_traits.h" + +namespace mojo { + +template <> +struct CloneTraits<content::mojom::PrefetchedSignedExchangeInfoPtr, true> { + static content::mojom::PrefetchedSignedExchangeInfoPtr Clone( + const content::mojom::PrefetchedSignedExchangeInfoPtr& input) { + return content::mojom::PrefetchedSignedExchangeInfo::New( + mojo::Clone(input->outer_url), mojo::Clone(input->header_integrity), + mojo::Clone(input->inner_url), mojo::Clone(input->inner_response), + ScopedMessagePipeHandle()); + } +}; + +} // namespace mojo + +#endif // CONTENT_COMMON_NAVIGATION_PARAMS_MOJOM_TRAITS_H_
diff --git a/content/common/prefetched_signed_exchange_info.cc b/content/common/prefetched_signed_exchange_info.cc deleted file mode 100644 index 2f6fdca..0000000 --- a/content/common/prefetched_signed_exchange_info.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/common/prefetched_signed_exchange_info.h" - -namespace content { - -PrefetchedSignedExchangeInfo::PrefetchedSignedExchangeInfo() = default; -PrefetchedSignedExchangeInfo::PrefetchedSignedExchangeInfo( - const PrefetchedSignedExchangeInfo&) = default; -PrefetchedSignedExchangeInfo::PrefetchedSignedExchangeInfo( - const GURL& outer_url, - const net::SHA256HashValue& header_integrity, - const GURL& inner_url, - const network::ResourceResponseHead& inner_response, - mojo::MessagePipeHandle loader_factory_handle) - : outer_url(outer_url), - header_integrity(header_integrity), - inner_url(inner_url), - inner_response(inner_response), - loader_factory_handle(loader_factory_handle) {} -PrefetchedSignedExchangeInfo::~PrefetchedSignedExchangeInfo() = default; - -} // namespace content
diff --git a/content/common/prefetched_signed_exchange_info.h b/content/common/prefetched_signed_exchange_info.h deleted file mode 100644 index 3555c09..0000000 --- a/content/common/prefetched_signed_exchange_info.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_COMMON_PREFETCHED_SIGNED_EXCHANGE_INFO_H_ -#define CONTENT_COMMON_PREFETCHED_SIGNED_EXCHANGE_INFO_H_ - -#include "content/common/content_export.h" -#include "mojo/public/cpp/system/message_pipe.h" -#include "net/base/hash_value.h" -#include "services/network/public/cpp/resource_response.h" -#include "url/gurl.h" - -namespace content { - -// Used for SignedExchangeSubresourcePrefetch. -// This struct keeps the information about a prefetched signed exchange. It is -// used in CommitNavigationParams to be passed from the browser process to the -// renderer process in CommitNavigation IPC. -struct CONTENT_EXPORT PrefetchedSignedExchangeInfo { - PrefetchedSignedExchangeInfo(); - PrefetchedSignedExchangeInfo(const PrefetchedSignedExchangeInfo&); - PrefetchedSignedExchangeInfo( - const GURL& outer_url, - const net::SHA256HashValue& header_integrity, - const GURL& inner_url, - const network::ResourceResponseHead& inner_response, - mojo::MessagePipeHandle loader_factory_handle); - ~PrefetchedSignedExchangeInfo(); - - GURL outer_url; - net::SHA256HashValue header_integrity; - GURL inner_url; - network::ResourceResponseHead inner_response; - mojo::MessagePipeHandle loader_factory_handle; -}; - -} // namespace content - -#endif // CONTENT_COMMON_PREFETCHED_SIGNED_EXCHANGE_INFO_H_
diff --git a/content/common/prefetched_signed_exchange_info.mojom b/content/common/prefetched_signed_exchange_info.mojom new file mode 100644 index 0000000..521eea5 --- /dev/null +++ b/content/common/prefetched_signed_exchange_info.mojom
@@ -0,0 +1,23 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module content.mojom; + +import "services/network/public/mojom/url_loader.mojom"; +import "url/mojom/url.mojom"; + +[Native] +struct SHA256HashValue; + +// Used for SignedExchangeSubresourcePrefetch. +// This struct keeps the information about a prefetched signed exchange. It is +// used in CommitNavigationParams to be passed from the browser process to the +// renderer process in CommitNavigation IPC. +struct PrefetchedSignedExchangeInfo { + url.mojom.Url outer_url; + SHA256HashValue header_integrity; + url.mojom.Url inner_url; + network.mojom.URLResponseHead inner_response; + handle<message_pipe> loader_factory_handle; +};
diff --git a/content/common/renderer.mojom b/content/common/renderer.mojom index cc97bb7..860f29a0 100644 --- a/content/common/renderer.mojom +++ b/content/common/renderer.mojom
@@ -157,6 +157,14 @@ bool scroll_view_rubber_banding; }; +struct UpdateSystemColorInfoParams { + bool is_dark_mode; + bool is_high_contrast; + PreferredColorScheme preferred_color_scheme; + // uint32 represents a SkColor in the map. + map<SystemThemeColor, uint32> colors; +}; + enum RenderProcessState { kVisible, // Hidden render processes can still be foregrounded. For example, a hidden @@ -244,6 +252,9 @@ OnSystemColorsChanged(int32 aqua_color_variant, string highlight_text_color, string highlight_color); + // Tells the renderer process the new system color info. + UpdateSystemColorInfo(UpdateSystemColorInfoParams params); + // Tells the renderer to empty its plugin list cache, optional reloading // pages containing plugins. PurgePluginListCache(bool reload_pages);
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index d78e27e2..632b7b8 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -55,6 +55,7 @@ #include "ui/gfx/ipc/color/gfx_param_traits.h" #include "ui/gfx/ipc/gfx_param_traits.h" #include "ui/gfx/ipc/skia/gfx_skia_param_traits.h" +#include "ui/native_theme/native_theme.h" #if defined(OS_MACOSX) #include "third_party/blink/public/platform/mac/web_scrollbar_theme.h" @@ -86,6 +87,11 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::ScrollerStyle, blink::kScrollerStyleOverlay) #endif +IPC_ENUM_TRAITS_MAX_VALUE(ui::NativeTheme::PreferredColorScheme, + ui::NativeTheme::PreferredColorScheme::kMaxValue) +IPC_ENUM_TRAITS_MAX_VALUE(ui::NativeTheme::SystemThemeColor, + ui::NativeTheme::SystemThemeColor::kMaxValue) + IPC_STRUCT_TRAITS_BEGIN(blink::WebPluginAction) IPC_STRUCT_TRAITS_MEMBER(type) IPC_STRUCT_TRAITS_MEMBER(enable)
diff --git a/content/public/test/content_mock_cert_verifier.cc b/content/public/test/content_mock_cert_verifier.cc index 8e2e379..3b25a01 100644 --- a/content/public/test/content_mock_cert_verifier.cc +++ b/content/public/test/content_mock_cert_verifier.cc
@@ -68,7 +68,7 @@ void ContentMockCertVerifier::CertVerifier:: EnsureNetworkServiceTestInitialized() { - if (!network_service_test_) { + if (!network_service_test_ || network_service_test_.encountered_error()) { GetSystemConnector()->BindInterface(mojom::kNetworkServiceName, &network_service_test_); }
diff --git a/content/renderer/input/input_event_prediction_unittest.cc b/content/renderer/input/input_event_prediction_unittest.cc index 2bd7889..621445b 100644 --- a/content/renderer/input/input_event_prediction_unittest.cc +++ b/content/renderer/input/input_event_prediction_unittest.cc
@@ -108,9 +108,9 @@ ConfigureFieldTrialAndInitialize( features::kResamplingInputEvents, - ui::input_prediction::kScrollPredictorNameKalmanTimeFiltered); + ui::input_prediction::kScrollPredictorNameKalman); EXPECT_EQ(event_predictor_->selected_predictor_type_, - PredictorType::kScrollPredictorTypeKalmanTimeFiltered); + PredictorType::kScrollPredictorTypeKalman); ConfigureFieldTrialAndInitialize( features::kResamplingInputEvents, @@ -407,7 +407,7 @@ TEST_F(InputEventPredictionTest, PredictedEventsTimeIntervalEqualRealEvents) { ConfigureFieldTrialAndInitialize( features::kResamplingInputEvents, - ui::input_prediction::kScrollPredictorNameKalmanTimeFiltered); + ui::input_prediction::kScrollPredictorNameKalman); base::TimeTicks event_time = ui::EventTimeForNow(); // Send 3 mouse move each has 6ms interval to get kalman predictor ready.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index af69214..4b16625 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -59,6 +59,7 @@ #include "content/common/input_messages.h" #include "content/common/navigation_gesture.h" #include "content/common/navigation_params.h" +#include "content/common/navigation_params_mojom_traits.h" #include "content/common/navigation_params_utils.h" #include "content/common/page_messages.h" #include "content/common/renderer_host.mojom.h" @@ -498,17 +499,17 @@ for (const auto& exchange : commit_params.prefetched_signed_exchanges) { blink::WebURLResponse web_response; WebURLLoaderImpl::PopulateURLResponse( - exchange.inner_url, exchange.inner_response, &web_response, + exchange->inner_url, exchange->inner_response, &web_response, false /* report_security_info*/, -1 /* request_id */); navigation_params->prefetched_signed_exchanges.emplace_back( std::make_unique< blink::WebNavigationParams::PrefetchedSignedExchange>( - exchange.outer_url, + exchange->outer_url, WebString::FromLatin1( signed_exchange_utils::CreateHeaderIntegrityHashString( - exchange.header_integrity)), - exchange.inner_url, web_response, - mojo::ScopedMessagePipeHandle(exchange.loader_factory_handle))); + exchange->header_integrity)), + exchange->inner_url, web_response, + std::move(exchange->loader_factory_handle))); } }
diff --git a/content/renderer/render_frame_impl_browsertest.cc b/content/renderer/render_frame_impl_browsertest.cc index db19505..4385beb5 100644 --- a/content/renderer/render_frame_impl_browsertest.cc +++ b/content/renderer/render_frame_impl_browsertest.cc
@@ -19,6 +19,7 @@ #include "build/build_config.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" +#include "content/common/navigation_params_mojom_traits.h" #include "content/common/renderer.mojom.h" #include "content/common/unfreezable_frame_messages.h" #include "content/common/widget_messages.h"
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 03f7b2c..bff56efdb 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -2158,6 +2158,13 @@ #endif } +void RenderThreadImpl::UpdateSystemColorInfo( + mojom::UpdateSystemColorInfoParamsPtr params) { + ui::NativeTheme::GetInstanceForWeb()->UpdateSystemColorInfo( + params->is_dark_mode, params->is_high_contrast, + params->preferred_color_scheme, params->colors); +} + void RenderThreadImpl::PurgePluginListCache(bool reload_pages) { #if BUILDFLAG(ENABLE_PLUGINS) blink::ResetPluginCache(reload_pages);
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 1470459..8a22ef7 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -534,6 +534,8 @@ void OnSystemColorsChanged(int32_t aqua_color_variant, const std::string& highlight_text_color, const std::string& highlight_color) override; + void UpdateSystemColorInfo( + mojom::UpdateSystemColorInfoParamsPtr params) override; void PurgePluginListCache(bool reload_pages) override; void SetProcessState(mojom::RenderProcessState process_state) override; void SetSchedulerKeepActive(bool keep_active) override;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 6139273..de997ab 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -669,7 +669,6 @@ settings->SetJavaScriptCanAccessClipboard( prefs.javascript_can_access_clipboard); WebRuntimeFeatures::EnableXSLT(prefs.xslt_enabled); - settings->SetXSSAuditorEnabled(prefs.xss_auditor_enabled); settings->SetDNSPrefetchingEnabled(prefs.dns_prefetching_enabled); blink::WebNetworkStateNotifier::SetSaveDataEnabled(prefs.data_saver_enabled); settings->SetLocalStorageEnabled(prefs.local_storage_enabled);
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 472569f4..5bf3288c 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -76,6 +76,12 @@ "../browser/service_worker/service_worker_test_utils.h", "../browser/service_worker/test_service_worker_observer.cc", "../browser/service_worker/test_service_worker_observer.h", + "../browser/sms/test/mock_sms_dialog.cc", + "../browser/sms/test/mock_sms_dialog.h", + "../browser/sms/test/mock_sms_provider.cc", + "../browser/sms/test/mock_sms_provider.h", + "../browser/sms/test/mock_sms_web_contents_delegate.cc", + "../browser/sms/test/mock_sms_web_contents_delegate.h", "../browser/web_package/mock_bundled_exchanges_reader_factory.cc", "../browser/web_package/mock_bundled_exchanges_reader_factory.h", "../browser/web_package/mock_signed_exchange_handler.cc",
diff --git a/docs/ui/android/night_mode.md b/docs/ui/android/night_mode.md index 26ae1bd7..d6693be 100644 --- a/docs/ui/android/night_mode.md +++ b/docs/ui/android/night_mode.md
@@ -144,7 +144,7 @@ * Turn on power save mode (aka **battery saver**) on Android P+ * Go to **Android Settings -> Developer options -> Night mode** on Android P * Go to **Android Settings -> Display -> Theme** on Android Q -* [Set color scheme](https://cs.chromium.org/chromium/src/third_party/android_sdk/androidx_browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java?) to `COLOR_SCHEME_DARK` on creating a `CustomTabsIntent.Builder` +* [Set color scheme](https://cs.chromium.org/chromium/src/third_party/custom_tabs_client/src/customtabs/src/android/support/customtabs/CustomTabsIntent.java?) to `COLOR_SCHEME_DARK` on creating a `CustomTabsIntent.Builder` Some tips:
diff --git a/docs/webui_explainer.md b/docs/webui_explainer.md index 3b9bd04c..80b4f69 100644 --- a/docs/webui_explainer.md +++ b/docs/webui_explainer.md
@@ -218,7 +218,7 @@ base::Bind(&OvenHandler::HandleBakeDonuts, base::Unretained(this))); } -void OverHandler::HandleBakeDonuts(const base::ListValue* args) { +void OvenHandler::HandleBakeDonuts(const base::ListValue* args) { AllowJavascript(); CHECK_EQ(1u, args->GetSize());
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 79ad0b7..3400986 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -619,6 +619,7 @@ "extension_pref_value_map_unittest.cc", "extension_registrar_unittest.cc", "extension_registry_unittest.cc", + "extension_util_unittest.cc", "file_highlighter_unittest.cc", "file_reader_unittest.cc", "image_loader_unittest.cc",
diff --git a/extensions/browser/api/declarative_net_request/constants.cc b/extensions/browser/api/declarative_net_request/constants.cc index 784ecb40fc..73a6f3e0 100644 --- a/extensions/browser/api/declarative_net_request/constants.cc +++ b/extensions/browser/api/declarative_net_request/constants.cc
@@ -49,6 +49,9 @@ "values are: [*]."; const char kErrorQueryAndTransformBothSpecified[] = "Rule with id * cannot specify both \"*\" and \"*\" keys."; +const char kErrorJavascriptRedirect[] = + "Rule with id * specifies an incorrect value for the \"*\" key. Redirects " + "to javascript urls are not supported."; const char kErrorListNotPassed[] = "Rules file must contain a list."; const char kRuleCountExceeded[] =
diff --git a/extensions/browser/api/declarative_net_request/constants.h b/extensions/browser/api/declarative_net_request/constants.h index 9b83bd3..71a478a 100644 --- a/extensions/browser/api/declarative_net_request/constants.h +++ b/extensions/browser/api/declarative_net_request/constants.h
@@ -44,6 +44,7 @@ ERROR_INVALID_TRANSFORM_QUERY, ERROR_INVALID_TRANSFORM_FRAGMENT, ERROR_QUERY_AND_TRANSFORM_BOTH_SPECIFIED, + ERROR_JAVASCRIPT_REDIRECT, }; // Describes the ways in which updating dynamic rules can fail. @@ -107,6 +108,7 @@ extern const char kErrorInvalidKey[]; extern const char kErrorInvalidTransformScheme[]; extern const char kErrorQueryAndTransformBothSpecified[]; +extern const char kErrorJavascriptRedirect[]; extern const char kErrorListNotPassed[];
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule.cc b/extensions/browser/api/declarative_net_request/indexed_rule.cc index 8d8bf33..aa20994 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule.cc
@@ -16,6 +16,7 @@ #include "extensions/common/api/declarative_net_request.h" #include "extensions/common/api/declarative_net_request/utils.h" #include "url/gurl.h" +#include "url/url_constants.h" namespace extensions { namespace declarative_net_request { @@ -314,9 +315,13 @@ DCHECK(indexed_rule); if (redirect.url) { - if (!GURL(*redirect.url).is_valid()) + GURL redirect_url = GURL(*redirect.url); + if (!redirect_url.is_valid()) return ParseResult::ERROR_INVALID_REDIRECT_URL; + if (redirect_url.SchemeIs(url::kJavaScriptScheme)) + return ParseResult::ERROR_JAVASCRIPT_REDIRECT; + indexed_rule->redirect_url = std::move(*redirect.url); return ParseResult::SUCCESS; } @@ -326,6 +331,10 @@ return ParseResult::ERROR_INVALID_EXTENSION_PATH; GURL redirect_url = base_url.Resolve(*redirect.extension_path); + + // Sanity check that Resolve works as expected. + DCHECK_EQ(base_url.GetOrigin(), redirect_url.GetOrigin()); + if (!redirect_url.is_valid()) return ParseResult::ERROR_INVALID_EXTENSION_PATH; @@ -373,8 +382,6 @@ } if (is_redirect_rule) { - // TODO(crbug.com/983685): Prevent extensions from specifying redirects to - // Javascript urls. if (!parsed_rule.action.redirect) return ParseResult::ERROR_INVALID_REDIRECT;
diff --git a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc index 4913da0d..353465f 100644 --- a/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc +++ b/extensions/browser/api/declarative_net_request/indexed_rule_unittest.cc
@@ -505,6 +505,11 @@ base::nullopt }, { + R"({"url": "javascript:window.alert(\"hello,world\");"})", + ParseResult::ERROR_JAVASCRIPT_REDIRECT, + base::nullopt + }, + { R"({"url": "http://google.com"})", ParseResult::SUCCESS, std::string("http://google.com")
diff --git a/extensions/browser/api/declarative_net_request/indexed_ruleset_format_version_unittest.cc b/extensions/browser/api/declarative_net_request/indexed_ruleset_format_version_unittest.cc index 2ee019ff..e08e5832 100644 --- a/extensions/browser/api/declarative_net_request/indexed_ruleset_format_version_unittest.cc +++ b/extensions/browser/api/declarative_net_request/indexed_ruleset_format_version_unittest.cc
@@ -125,7 +125,7 @@ EXPECT_EQ(StripCommentsAndWhitespace(kFlatbufferSchemaExpected), StripCommentsAndWhitespace(flatbuffer_schema)) << "Schema change detected; update this test and the schema version."; - EXPECT_EQ(9, GetIndexedRulesetFormatVersionForTesting()) + EXPECT_EQ(10, GetIndexedRulesetFormatVersionForTesting()) << "Update this test if you update the schema version."; }
diff --git a/extensions/browser/api/declarative_net_request/parse_info.cc b/extensions/browser/api/declarative_net_request/parse_info.cc index a2e1e0b..802f3caa 100644 --- a/extensions/browser/api/declarative_net_request/parse_info.cc +++ b/extensions/browser/api/declarative_net_request/parse_info.cc
@@ -150,6 +150,12 @@ error = ErrorUtils::FormatErrorMessage( kErrorQueryAndTransformBothSpecified, base::NumberToString(*rule_id_), kTransformQueryPath, kTransformQueryTransformPath); + break; + case ParseResult::ERROR_JAVASCRIPT_REDIRECT: + error = ErrorUtils::FormatErrorMessage(kErrorJavascriptRedirect, + base::NumberToString(*rule_id_), + kRedirectUrlPath); + break; } return error; }
diff --git a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc index 9e2cebc..8c08200 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_matcher.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_matcher.cc
@@ -25,6 +25,7 @@ #include "net/base/escape.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" #include "net/base/url_util.h" +#include "url/url_constants.h" namespace extensions { namespace declarative_net_request { @@ -407,6 +408,12 @@ else *redirect_url = GetTransformedURL(params, *metadata->transform()); + // Sanity check that we don't redirect to a javascript url. Specifying + // redirect to a javascript url and specifying javascript as a transform + // scheme is prohibited. In addition extensions can't intercept requests to + // javascript urls. Hence we should never end up with a javascript url here. + DCHECK(!redirect_url->SchemeIs(url::kJavaScriptScheme)); + // Prevent a redirect loop where a URL continuously redirects to itself. return (redirect_url->is_valid() && *params.url != *redirect_url) ? rule : nullptr;
diff --git a/extensions/browser/api/declarative_net_request/utils.cc b/extensions/browser/api/declarative_net_request/utils.cc index e73f3e4..393db78 100644 --- a/extensions/browser/api/declarative_net_request/utils.cc +++ b/extensions/browser/api/declarative_net_request/utils.cc
@@ -33,7 +33,7 @@ // url_pattern_index.fbs. Whenever an extension with an indexed ruleset format // version different from the one currently used by Chrome is loaded, the // extension ruleset will be reindexed. -constexpr int kIndexedRulesetFormatVersion = 9; +constexpr int kIndexedRulesetFormatVersion = 10; // This static assert is meant to catch cases where // url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
diff --git a/extensions/browser/extension_util.cc b/extensions/browser/extension_util.cc index 2ad8528f..6077d4e 100644 --- a/extensions/browser/extension_util.cc +++ b/extensions/browser/extension_util.cc
@@ -13,6 +13,7 @@ #include "extensions/common/features/feature_provider.h" #include "extensions/common/manifest.h" #include "extensions/common/manifest_handlers/incognito_info.h" +#include "extensions/common/manifest_handlers/shared_module_info.h" namespace extensions { namespace util { @@ -68,5 +69,64 @@ return storage_partition; } +// This function is security sensitive. Bugs could cause problems that break +// restrictions on local file access or NaCl's validation caching. If you modify +// this function, please get a security review from a NaCl person. +bool MapUrlToLocalFilePath(const ExtensionSet* extensions, + const GURL& file_url, + bool use_blocking_api, + base::FilePath* file_path) { + // Check that the URL is recognized by the extension system. + const Extension* extension = extensions->GetExtensionOrAppByURL(file_url); + if (!extension) + return false; + + // This is a short-cut which avoids calling a blocking file operation + // (GetFilePath()), so that this can be called on the non blocking threads. It + // only handles a subset of the urls. + if (!use_blocking_api) { + if (file_url.SchemeIs(extensions::kExtensionScheme)) { + std::string path = file_url.path(); + base::TrimString(path, "/", &path); // Remove first slash + *file_path = extension->path().AppendASCII(path); + return true; + } + return false; + } + + std::string path = file_url.path(); + ExtensionResource resource; + + if (SharedModuleInfo::IsImportedPath(path)) { + // Check if this is a valid path that is imported for this extension. + std::string new_extension_id; + std::string new_relative_path; + SharedModuleInfo::ParseImportedPath(path, &new_extension_id, + &new_relative_path); + const Extension* new_extension = extensions->GetByID(new_extension_id); + if (!new_extension) + return false; + + if (!SharedModuleInfo::ImportsExtensionById(extension, new_extension_id)) + return false; + + resource = new_extension->GetResource(new_relative_path); + } else { + // Check that the URL references a resource in the extension. + resource = extension->GetResource(path); + } + + if (resource.empty()) + return false; + + // GetFilePath is a blocking function call. + const base::FilePath resource_file_path = resource.GetFilePath(); + if (resource_file_path.empty()) + return false; + + *file_path = resource_file_path; + return true; +} + } // namespace util } // namespace extensions
diff --git a/extensions/browser/extension_util.h b/extensions/browser/extension_util.h index 05fc35f8..d8138ed 100644 --- a/extensions/browser/extension_util.h +++ b/extensions/browser/extension_util.h
@@ -9,6 +9,10 @@ #include "url/gurl.h" +namespace base { +class FilePath; +} + namespace content { class BrowserContext; class StoragePartition; @@ -16,6 +20,7 @@ namespace extensions { class Extension; +class ExtensionSet; namespace util { @@ -44,6 +49,17 @@ const std::string& extension_id, content::BrowserContext* browser_context); +// Maps a |file_url| to a |file_path| on the local filesystem, including +// resources in extensions. Returns true on success. See NaClBrowserDelegate for +// full details. If |use_blocking_api| is false, only a subset of URLs will be +// handled. If |use_blocking_api| is true, blocking file operations may be used, +// and this must be called on threads that allow blocking. Otherwise this can be +// called on any thread. +bool MapUrlToLocalFilePath(const ExtensionSet* extensions, + const GURL& file_url, + bool use_blocking_api, + base::FilePath* file_path); + } // namespace util } // namespace extensions
diff --git a/extensions/browser/extension_util_unittest.cc b/extensions/browser/extension_util_unittest.cc new file mode 100644 index 0000000..6efa6e7 --- /dev/null +++ b/extensions/browser/extension_util_unittest.cc
@@ -0,0 +1,59 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/extension_util.h" + +#include "base/path_service.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/extension_paths.h" +#include "extensions/common/extension_set.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace extensions { +namespace { +// Returns a barebones test Extension object with the given name. +static scoped_refptr<const Extension> CreateExtension(const std::string& name) { + base::FilePath path; + base::PathService::Get(DIR_TEST_DATA, &path); + + return ExtensionBuilder(name).SetPath(path.AppendASCII(name)).Build(); +} +} // namespace + +// Tests that extension URLs are properly mapped to local file paths. +TEST(ExtensionUtilTest, MapUrlToLocalFilePath) { + scoped_refptr<const Extension> app(CreateExtension("platform_app")); + ExtensionSet extensions; + extensions.Insert(app); + + // Non-extension URLs don't map to anything. + base::FilePath non_extension_path; + GURL non_extension_url("http://not-an-extension.com/"); + EXPECT_FALSE(util::MapUrlToLocalFilePath(&extensions, non_extension_url, + false, &non_extension_path)); + EXPECT_TRUE(non_extension_path.empty()); + + // Valid resources return a valid path. + base::FilePath valid_path; + GURL valid_url = app->GetResourceURL("manifest.json"); + EXPECT_TRUE(util::MapUrlToLocalFilePath( + &extensions, valid_url, true /* use_blocking_api */, &valid_path)); + EXPECT_FALSE(valid_path.empty()); + + // A file must exist to be mapped to a path using the blocking API. + base::FilePath does_not_exist_path; + GURL does_not_exist_url = app->GetResourceURL("does-not-exist.html"); + EXPECT_FALSE(util::MapUrlToLocalFilePath(&extensions, does_not_exist_url, + true /* use_blocking_api */, + &does_not_exist_path)); + EXPECT_TRUE(does_not_exist_path.empty()); + + // A file does not need to exist to be mapped to a path with the non-blocking + // API. This avoids hitting the disk to see if it exists. + EXPECT_TRUE(util::MapUrlToLocalFilePath(&extensions, does_not_exist_url, + false /* use_blocking_api */, + &does_not_exist_path)); + EXPECT_FALSE(does_not_exist_path.empty()); +} +} // namespace extensions
diff --git a/extensions/browser/info_map.cc b/extensions/browser/info_map.cc index 39c077a..497e73e4 100644 --- a/extensions/browser/info_map.cc +++ b/extensions/browser/info_map.cc
@@ -12,7 +12,6 @@ #include "extensions/common/extension_resource.h" #include "extensions/common/extension_set.h" #include "extensions/common/manifest_handlers/incognito_info.h" -#include "extensions/common/manifest_handlers/shared_module_info.h" #include "extensions/common/permissions/permissions_data.h" #include "url/gurl.h" @@ -138,64 +137,6 @@ process_map_.RemoveAllFromProcess(process_id); } -// This function is security sensitive. Bugs could cause problems that break -// restrictions on local file access or NaCl's validation caching. If you modify -// this function, please get a security review from a NaCl person. -bool InfoMap::MapUrlToLocalFilePath(const GURL& file_url, - bool use_blocking_api, - base::FilePath* file_path) { - // Check that the URL is recognized by the extension system. - const Extension* extension = extensions_.GetExtensionOrAppByURL(file_url); - if (!extension) - return false; - - // This is a short-cut which avoids calling a blocking file operation - // (GetFilePath()), so that this can be called on the IO thread. It only - // handles a subset of the urls. - if (!use_blocking_api) { - if (file_url.SchemeIs(extensions::kExtensionScheme)) { - std::string path = file_url.path(); - base::TrimString(path, "/", &path); // Remove first slash - *file_path = extension->path().AppendASCII(path); - return true; - } - return false; - } - - std::string path = file_url.path(); - ExtensionResource resource; - - if (SharedModuleInfo::IsImportedPath(path)) { - // Check if this is a valid path that is imported for this extension. - std::string new_extension_id; - std::string new_relative_path; - SharedModuleInfo::ParseImportedPath( - path, &new_extension_id, &new_relative_path); - const Extension* new_extension = extensions_.GetByID(new_extension_id); - if (!new_extension) - return false; - - if (!SharedModuleInfo::ImportsExtensionById(extension, new_extension_id)) - return false; - - resource = new_extension->GetResource(new_relative_path); - } else { - // Check that the URL references a resource in the extension. - resource = extension->GetResource(path); - } - - if (resource.empty()) - return false; - - // GetFilePath is a blocking function call. - const base::FilePath resource_file_path = resource.GetFilePath(); - if (resource_file_path.empty()) - return false; - - *file_path = resource_file_path; - return true; -} - QuotaService* InfoMap::GetQuotaService() { CheckOnValidThread(); if (!quota_service_)
diff --git a/extensions/browser/info_map.h b/extensions/browser/info_map.h index 414ceba..e56bf890 100644 --- a/extensions/browser/info_map.h +++ b/extensions/browser/info_map.h
@@ -16,10 +16,6 @@ #include "extensions/common/extension_set.h" #include "extensions/common/permissions/api_permission.h" -namespace base { -class FilePath; -} - namespace extensions { class ContentVerifier; class Extension; @@ -72,13 +68,6 @@ int site_instance_id); void UnregisterAllExtensionsInProcess(int process_id); - // Maps a |file_url| to a |file_path| on the local filesystem, including - // resources in extensions. Returns true on success. See NaClBrowserDelegate - // for full details. - bool MapUrlToLocalFilePath(const GURL& file_url, - bool use_blocking_api, - base::FilePath* file_path); - // Returns the IO thread QuotaService. Creates the instance on first call. QuotaService* GetQuotaService();
diff --git a/extensions/browser/info_map_unittest.cc b/extensions/browser/info_map_unittest.cc index 5a8d6e0..23fd5641 100644 --- a/extensions/browser/info_map_unittest.cc +++ b/extensions/browser/info_map_unittest.cc
@@ -79,38 +79,4 @@ EXPECT_EQ(extension2.get(), info_map->extensions().GetByID(extension2->id())); } -// Tests that extension URLs are properly mapped to local file paths. -TEST_F(InfoMapTest, MapUrlToLocalFilePath) { - scoped_refptr<InfoMap> info_map(new InfoMap()); - scoped_refptr<const Extension> app(CreateExtension("platform_app")); - info_map->AddExtension(app.get(), base::Time(), false, false); - - // Non-extension URLs don't map to anything. - base::FilePath non_extension_path; - GURL non_extension_url("http://not-an-extension.com/"); - EXPECT_FALSE(info_map->MapUrlToLocalFilePath( - non_extension_url, false, &non_extension_path)); - EXPECT_TRUE(non_extension_path.empty()); - - // Valid resources return a valid path. - base::FilePath valid_path; - GURL valid_url = app->GetResourceURL("manifest.json"); - EXPECT_TRUE(info_map->MapUrlToLocalFilePath( - valid_url, true /* use_blocking_api */, &valid_path)); - EXPECT_FALSE(valid_path.empty()); - - // A file must exist to be mapped to a path using the blocking API. - base::FilePath does_not_exist_path; - GURL does_not_exist_url = app->GetResourceURL("does-not-exist.html"); - EXPECT_FALSE(info_map->MapUrlToLocalFilePath( - does_not_exist_url, true /* use_blocking_api */, &does_not_exist_path)); - EXPECT_TRUE(does_not_exist_path.empty()); - - // A file does not need to exist to be mapped to a path with the non-blocking - // API. This avoids hitting the disk to see if it exists. - EXPECT_TRUE(info_map->MapUrlToLocalFilePath( - does_not_exist_url, false /* use_blocking_api */, &does_not_exist_path)); - EXPECT_FALSE(does_not_exist_path.empty()); -} - } // namespace extensions
diff --git a/extensions/common/api/declarative_net_request.idl b/extensions/common/api/declarative_net_request.idl index f255773..8f7e388 100644 --- a/extensions/common/api/declarative_net_request.idl +++ b/extensions/common/api/declarative_net_request.idl
@@ -72,7 +72,8 @@ // Describes modification to various url components. dictionary URLTransform { - // The new scheme for the request. + // The new scheme for the request. Allowed values are "http", "https", + // "ftp" and "chrome-extension". DOMString? scheme; // The new host for the request. @@ -107,7 +108,7 @@ DOMString? extensionPath; // Url transformations to perform. URLTransform? transform; - // The redirect url. + // The redirect url. Redirects to JavaScript urls are not allowed. DOMString? url; };
diff --git a/extensions/shell/browser/shell_nacl_browser_delegate.cc b/extensions/shell/browser/shell_nacl_browser_delegate.cc index ed4cfbc..5416340 100644 --- a/extensions/shell/browser/shell_nacl_browser_delegate.cc +++ b/extensions/shell/browser/shell_nacl_browser_delegate.cc
@@ -17,8 +17,8 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/site_instance.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" -#include "extensions/browser/info_map.h" #include "extensions/browser/process_manager.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -109,47 +109,49 @@ // person before you modify it. // TODO(jamescook): Refactor this code into the extensions module so it can // be shared with Chrome's NaClBrowserDelegateImpl. http://crbug.com/403017 -bool ShellNaClBrowserDelegate::MapUrlToLocalFilePath( - const GURL& file_url, - bool use_blocking_api, - const base::FilePath& profile_directory, - base::FilePath* file_path) { - ExtensionSystem* extension_system = ExtensionSystem::Get(browser_context_); - DCHECK(extension_system); +NaClBrowserDelegate::MapUrlToLocalFilePathCallback +ShellNaClBrowserDelegate::GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) { + auto extensions = std::make_unique<ExtensionSet>(); + extensions->InsertAll( + ExtensionRegistry::Get(browser_context_)->enabled_extensions()); + return base::BindRepeating( + [](const ExtensionSet* extensions, const GURL& file_url, + bool use_blocking_api, base::FilePath* file_path) { + // Check that the URL is recognized by the extension system. + const Extension* extension = + extensions->GetExtensionOrAppByURL(file_url); + if (!extension) + return false; - // Check that the URL is recognized by the extension system. - const Extension* extension = - extension_system->info_map()->extensions().GetExtensionOrAppByURL( - file_url); - if (!extension) - return false; + // This is a short-cut which avoids calling a blocking file operation + // (GetFilePath()), so that this can be called on the IO thread. It only + // handles a subset of the urls. + if (!use_blocking_api) { + if (file_url.SchemeIs(kExtensionScheme)) { + std::string path = file_url.path(); + base::TrimString(path, "/", &path); // Remove first slash + *file_path = extension->path().AppendASCII(path); + return true; + } + return false; + } - // This is a short-cut which avoids calling a blocking file operation - // (GetFilePath()), so that this can be called on the IO thread. It only - // handles a subset of the urls. - if (!use_blocking_api) { - if (file_url.SchemeIs(kExtensionScheme)) { - std::string path = file_url.path(); - base::TrimString(path, "/", &path); // Remove first slash - *file_path = extension->path().AppendASCII(path); - return true; - } - return false; - } + // Check that the URL references a resource in the extension. + // NOTE: app_shell does not support shared modules. + ExtensionResource resource = extension->GetResource(file_url.path()); + if (resource.empty()) + return false; - // Check that the URL references a resource in the extension. - // NOTE: app_shell does not support shared modules. - ExtensionResource resource = extension->GetResource(file_url.path()); - if (resource.empty()) - return false; + // GetFilePath is a blocking function call. + const base::FilePath resource_file_path = resource.GetFilePath(); + if (resource_file_path.empty()) + return false; - // GetFilePath is a blocking function call. - const base::FilePath resource_file_path = resource.GetFilePath(); - if (resource_file_path.empty()) - return false; - - *file_path = resource_file_path; - return true; + *file_path = resource_file_path; + return true; + }, + base::Owned(std::move(extensions))); } bool ShellNaClBrowserDelegate::IsNonSfiModeAllowed(
diff --git a/extensions/shell/browser/shell_nacl_browser_delegate.h b/extensions/shell/browser/shell_nacl_browser_delegate.h index 80907be..2a12e48 100644 --- a/extensions/shell/browser/shell_nacl_browser_delegate.h +++ b/extensions/shell/browser/shell_nacl_browser_delegate.h
@@ -35,10 +35,8 @@ std::string GetVersionString() const override; ppapi::host::HostFactory* CreatePpapiHostFactory( content::BrowserPpapiHost* ppapi_host) override; - bool MapUrlToLocalFilePath(const GURL& url, - bool is_blocking, - const base::FilePath& profile_directory, - base::FilePath* file_path) override; + MapUrlToLocalFilePathCallback GetMapUrlToLocalFilePathCallback( + const base::FilePath& profile_directory) override; void SetDebugPatterns(const std::string& debug_patterns) override; bool URLMatchesDebugPatterns(const GURL& manifest_url) override; bool IsNonSfiModeAllowed(const base::FilePath& profile_directory,
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn index 56841a8..6044a73 100644 --- a/fuchsia/BUILD.gn +++ b/fuchsia/BUILD.gn
@@ -14,7 +14,6 @@ "fidl/cast/api_bindings.fidl", "fidl/cast/application_config.fidl", "fidl/cast/application_controller.fidl", - "fidl/cast/queryable_data.fidl", ] public_deps = [
diff --git a/fuchsia/fidl/cast/queryable_data.fidl b/fuchsia/fidl/cast/queryable_data.fidl deleted file mode 100644 index c7148a139..0000000 --- a/fuchsia/fidl/cast/queryable_data.fidl +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2019 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. - -library chromium.cast; - -struct QueryableDataEntry { - string key; - string json_value; -}; - -/// Interface for serving configuration- and environmental-related values -/// to CastRunner instances. -[Discoverable] -protocol QueryableData { - /// Gets a list of changed entries since the last call to GetChangedEntries, - /// delaying execution of the the pending callback until a change becomes - /// available. The initial call will return all entries managed by the - /// QueryableData service. - GetChangedEntries() -> (vector<QueryableDataEntry> values); -}; -
diff --git a/fuchsia/runners/cast/fake_queryable_data.cc b/fuchsia/runners/cast/fake_queryable_data.cc deleted file mode 100644 index 4f3758d..0000000 --- a/fuchsia/runners/cast/fake_queryable_data.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "fuchsia/runners/cast/fake_queryable_data.h" - -#include <string> -#include <utility> -#include <vector> - -#include "base/json/json_writer.h" - -FakeQueryableData::FakeQueryableData() = default; - -FakeQueryableData::~FakeQueryableData() = default; - -void FakeQueryableData::SendChanges( - std::vector<std::pair<base::StringPiece, base::Value&&>> changes) { - for (const auto& change : changes) { - std::string value_json; - CHECK(base::JSONWriter::Write(change.second, &value_json)); - changes_.push_back({change.first.as_string(), value_json}); - } - - if (get_changed_callback_) - DeliverChanges(); -} - -void FakeQueryableData::GetChangedEntries(GetChangedEntriesCallback callback) { - DCHECK(!get_changed_callback_); - get_changed_callback_ = std::move(callback); - - if (!changes_.empty()) - DeliverChanges(); -} - -void FakeQueryableData::DeliverChanges() { - (*get_changed_callback_)(std::move(changes_)); - get_changed_callback_ = base::nullopt; -}
diff --git a/fuchsia/runners/cast/fake_queryable_data.h b/fuchsia/runners/cast/fake_queryable_data.h deleted file mode 100644 index 1c3f14d3..0000000 --- a/fuchsia/runners/cast/fake_queryable_data.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FUCHSIA_RUNNERS_CAST_FAKE_QUERYABLE_DATA_H_ -#define FUCHSIA_RUNNERS_CAST_FAKE_QUERYABLE_DATA_H_ - -#include <string> -#include <utility> -#include <vector> - -#include "base/macros.h" -#include "base/optional.h" -#include "base/strings/string_piece.h" -#include "base/values.h" -#include "fuchsia/fidl/chromium/cast/cpp/fidl.h" - -// A simple STL map-backed implementation of QueryableData, for testing -// purposes. -class FakeQueryableData : public chromium::cast::QueryableData { - public: - FakeQueryableData(); - ~FakeQueryableData() override; - - // Sends, or prepares to send, a set of changed values to the page. - void SendChanges( - std::vector<std::pair<base::StringPiece, base::Value&&>> changes); - - private: - void DeliverChanges(); - - // chromium::cast::QueryableData implementation. - void GetChangedEntries(GetChangedEntriesCallback callback) override; - - base::Optional<GetChangedEntriesCallback> get_changed_callback_; - std::vector<chromium::cast::QueryableDataEntry> changes_; - - DISALLOW_COPY_AND_ASSIGN(FakeQueryableData); -}; - -#endif // FUCHSIA_RUNNERS_CAST_FAKE_QUERYABLE_DATA_H_
diff --git a/ios/chrome/app/application_delegate/browser_launcher.h b/ios/chrome/app/application_delegate/browser_launcher.h index 6e1be2b..23e3f02e 100644 --- a/ios/chrome/app/application_delegate/browser_launcher.h +++ b/ios/chrome/app/application_delegate/browser_launcher.h
@@ -34,7 +34,9 @@ // Browser view information created during startup. @property(nonatomic, readonly) id<BrowserInterfaceProvider> interfaceProvider; -// Initializes the application up to |stage|. +// Initializes the application up to |stage|. This is safe to call multiple +// times for the same value of |stage|; the actions for each stage will only +// be run once during the lifetime of the app. - (void)startUpBrowserToStage:(BrowserInitializationStageType)stage; @end
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm index 537c166..bf2747f 100644 --- a/ios/chrome/app/main_application_delegate.mm +++ b/ios/chrome/app/main_application_delegate.mm
@@ -173,6 +173,10 @@ if ([_appState isInSafeMode]) return NO; + // Enusre Chrome is fuilly started up in case it had launched to the + // background. + [_browserLauncher startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND]; + return [UserActivityHandler willContinueUserActivityWithType:userActivityType]; } @@ -184,6 +188,10 @@ if ([_appState isInSafeMode]) return NO; + // Enusre Chrome is fuilly started up in case it had launched to the + // background. + [_browserLauncher startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND]; + BOOL applicationIsActive = [application applicationState] == UIApplicationStateActive; @@ -199,6 +207,10 @@ if ([_appState isInSafeMode]) return; + // Enusre Chrome is fuilly started up in case it had launched to the + // background. + [_browserLauncher startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND]; + [UserActivityHandler performActionForShortcutItem:shortcutItem completionHandler:completionHandler @@ -219,6 +231,13 @@ if ([_appState isInSafeMode]) return NO; + // The various URL handling mechanisms require that the application has + // fully started up; there are some cases (crbug.com/658420) where a + // launch via this method crashes because some services (specifically, + // CommandLine) aren't initialized yet. So: before anything further is + // done, make sure that Chrome is fully started up. + [_browserLauncher startUpBrowserToStage:INITIALIZATION_STAGE_FOREGROUND]; + if (ios::GetChromeBrowserProvider() ->GetChromeIdentityService() ->HandleApplicationOpenURL(application, url, options)) {
diff --git a/ios/chrome/app/memory_monitor.mm b/ios/chrome/app/memory_monitor.mm index c989736..5b99c4c 100644 --- a/ios/chrome/app/memory_monitor.mm +++ b/ios/chrome/app/memory_monitor.mm
@@ -37,7 +37,7 @@ static_cast<int>(base::SysInfo::AmountOfAvailablePhysicalMemory() / 1024); breakpad_helper::SetCurrentFreeMemoryInKB(free_memory); - NSURL* fileURL = [[NSURL alloc] initFileURLWithPath:@"/"]; + NSURL* fileURL = [[NSURL alloc] initFileURLWithPath:NSHomeDirectory()]; NSDictionary* results = [fileURL resourceValuesForKeys:@[ NSURLVolumeAvailableCapacityForImportantUsageKey ]
diff --git a/ios/chrome/browser/overlays/BUILD.gn b/ios/chrome/browser/overlays/BUILD.gn index 0985ace..22c60786 100644 --- a/ios/chrome/browser/overlays/BUILD.gn +++ b/ios/chrome/browser/overlays/BUILD.gn
@@ -6,10 +6,12 @@ public = [ "public/overlay_dismissal_callback.h", "public/overlay_modality.h", + "public/overlay_presentation_callback.h", "public/overlay_presentation_context.h", "public/overlay_presentation_context_observer.h", "public/overlay_presenter.h", "public/overlay_presenter_observer.h", + "public/overlay_presenter_observer_bridge.h", "public/overlay_request.h", "public/overlay_request_queue.h", "public/overlay_response.h", @@ -18,6 +20,7 @@ sources = [ "overlay_presenter_impl.h", "overlay_presenter_impl.mm", + "overlay_presenter_observer_bridge.mm", "overlay_request_impl.cc", "overlay_request_impl.h", "overlay_request_queue_impl.h", @@ -42,6 +45,7 @@ testonly = true sources = [ "overlay_presenter_impl_unittest.mm", + "overlay_presenter_observer_bridge_unittest.mm", "overlay_request_impl_unittest.cc", "overlay_request_queue_impl_unittest.mm", "overlay_request_unittest.cc",
diff --git a/ios/chrome/browser/overlays/overlay_presenter_impl.h b/ios/chrome/browser/overlays/overlay_presenter_impl.h index 7f3110c..8365b4d 100644 --- a/ios/chrome/browser/overlays/overlay_presenter_impl.h +++ b/ios/chrome/browser/overlays/overlay_presenter_impl.h
@@ -79,6 +79,13 @@ // only be called when |presenting_| is false. void PresentOverlayForActiveRequest(); + // Notifies this object that the UI for |request| has finished being + // presented in |presentation_context|. This function is called when the + // OverlayPresentationCallback provided to the presentation context is + // executed. + void OverlayWasPresented(OverlayPresentationContext* presentation_context, + OverlayRequest* request); + // Notifies this object that the UI for |request| has finished being dismissed // in |presentation_context| in for |reason|. |queue| is |request|'s queue. // This function is called when the OverlayDismissalCallback provided to
diff --git a/ios/chrome/browser/overlays/overlay_presenter_impl.mm b/ios/chrome/browser/overlays/overlay_presenter_impl.mm index 94f7fbb..a8f09d3 100644 --- a/ios/chrome/browser/overlays/overlay_presenter_impl.mm +++ b/ios/chrome/browser/overlays/overlay_presenter_impl.mm
@@ -200,13 +200,27 @@ } // Present the overlay UI via the UI delegate. + OverlayPresentationCallback presentation_callback = base::BindOnce( + &OverlayPresenterImpl::OverlayWasPresented, weak_factory_.GetWeakPtr(), + presentation_context_, request); OverlayDismissalCallback dismissal_callback = base::BindOnce( &OverlayPresenterImpl::OverlayWasDismissed, weak_factory_.GetWeakPtr(), presentation_context_, request, GetActiveQueue()->GetWeakPtr()); presentation_context_->ShowOverlayUI(this, request, + std::move(presentation_callback), std::move(dismissal_callback)); } +void OverlayPresenterImpl::OverlayWasPresented( + OverlayPresentationContext* presentation_context, + OverlayRequest* request) { + DCHECK_EQ(presentation_context_, presentation_context); + DCHECK_EQ(GetActiveRequest(), request); + for (auto& observer : observers_) { + observer.DidShowOverlay(this, request); + } +} + void OverlayPresenterImpl::OverlayWasDismissed( OverlayPresentationContext* presentation_context, OverlayRequest* request,
diff --git a/ios/chrome/browser/overlays/overlay_presenter_observer_bridge.mm b/ios/chrome/browser/overlays/overlay_presenter_observer_bridge.mm new file mode 100644 index 0000000..c68610e --- /dev/null +++ b/ios/chrome/browser/overlays/overlay_presenter_observer_bridge.mm
@@ -0,0 +1,51 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h" + +#include "base/logging.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +OverlayPresenterObserverBridge::OverlayPresenterObserverBridge( + id<OverlayPresenterObserving> observer) + : observer_(observer) { + DCHECK(observer_); +} + +OverlayPresenterObserverBridge::~OverlayPresenterObserverBridge() = default; + +void OverlayPresenterObserverBridge::WillShowOverlay( + OverlayPresenter* presenter, + OverlayRequest* request) { + if ([observer_ respondsToSelector:@selector(overlayPresenter: + willShowOverlayForRequest:)]) { + [observer_ overlayPresenter:presenter willShowOverlayForRequest:request]; + } +} + +void OverlayPresenterObserverBridge::DidShowOverlay(OverlayPresenter* presenter, + OverlayRequest* request) { + if ([observer_ respondsToSelector:@selector(overlayPresenter: + didShowOverlayForRequest:)]) { + [observer_ overlayPresenter:presenter didShowOverlayForRequest:request]; + } +} + +void OverlayPresenterObserverBridge::DidHideOverlay(OverlayPresenter* presenter, + OverlayRequest* request) { + if ([observer_ respondsToSelector:@selector(overlayPresenter: + didHideOverlayForRequest:)]) { + [observer_ overlayPresenter:presenter didHideOverlayForRequest:request]; + } +} + +void OverlayPresenterObserverBridge::OverlayPresenterDestroyed( + OverlayPresenter* presenter) { + if ([observer_ respondsToSelector:@selector(overlayPresenterDestroyed:)]) { + [observer_ overlayPresenterDestroyed:presenter]; + } +}
diff --git a/ios/chrome/browser/overlays/overlay_presenter_observer_bridge_unittest.mm b/ios/chrome/browser/overlays/overlay_presenter_observer_bridge_unittest.mm new file mode 100644 index 0000000..c36b612 --- /dev/null +++ b/ios/chrome/browser/overlays/overlay_presenter_observer_bridge_unittest.mm
@@ -0,0 +1,90 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h" + +#import <Foundation/Foundation.h> + +#include "testing/platform_test.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// Fake implementation of OverlayPresenterObserving that records whether the +// callbacks are executed. +@interface FakeOverlayPresenterObserver : NSObject <OverlayPresenterObserving> +// Whether each of the OverlayPresenterObserving callbacks have been called. +@property(nonatomic, readonly) BOOL willShowCalled; +@property(nonatomic, readonly) BOOL didShowCalled; +@property(nonatomic, readonly) BOOL didHideCalled; +@property(nonatomic, readonly) BOOL destroyedCalled; +@end + +@implementation FakeOverlayPresenterObserver + +- (void)overlayPresenter:(OverlayPresenter*)presenter + willShowOverlayForRequest:(OverlayRequest*)request { + _willShowCalled = YES; +} + +- (void)overlayPresenter:(OverlayPresenter*)presenter + didShowOverlayForRequest:(OverlayRequest*)request { + _didShowCalled = YES; +} + +- (void)overlayPresenter:(OverlayPresenter*)presenter + didHideOverlayForRequest:(OverlayRequest*)request { + _didHideCalled = YES; +} + +- (void)overlayPresenterDestroyed:(OverlayPresenter*)presenter { + _destroyedCalled = YES; +} + +@end + +// Test fixture for OverlayPresenterObserverBridge. +class OverlayPresenterObserverBridgeTest : public PlatformTest { + public: + OverlayPresenterObserverBridgeTest() + : observer_([[FakeOverlayPresenterObserver alloc] init]), + bridge_(observer_) {} + + protected: + FakeOverlayPresenterObserver* observer_; + OverlayPresenterObserverBridge bridge_; +}; + +// Tests that OverlayPresenterObserver::WillShowOverlay() is correctly +// forwarded. +TEST_F(OverlayPresenterObserverBridgeTest, WillShowCalled) { + ASSERT_FALSE(observer_.willShowCalled); + bridge_.WillShowOverlay(nullptr, nullptr); + EXPECT_TRUE(observer_.willShowCalled); +} + +// Tests that OverlayPresenterObserver::DidShowOverlay() is correctly +// forwarded. +TEST_F(OverlayPresenterObserverBridgeTest, DidShowCalled) { + ASSERT_FALSE(observer_.didShowCalled); + bridge_.DidShowOverlay(nullptr, nullptr); + EXPECT_TRUE(observer_.didShowCalled); +} + +// Tests that OverlayPresenterObserver::DidHideOverlay() is correctly +// forwarded. +TEST_F(OverlayPresenterObserverBridgeTest, DidHideCalled) { + ASSERT_FALSE(observer_.didHideCalled); + bridge_.DidHideOverlay(nullptr, nullptr); + EXPECT_TRUE(observer_.didHideCalled); +} + +// Tests that OverlayPresenterObserver::OverlayPresenterDestroyed() is correctly +// forwarded. +TEST_F(OverlayPresenterObserverBridgeTest, DestroyedCalled) { + ASSERT_FALSE(observer_.destroyedCalled); + bridge_.OverlayPresenterDestroyed(nullptr); + EXPECT_TRUE(observer_.destroyedCalled); +}
diff --git a/ios/chrome/browser/overlays/public/overlay_presentation_callback.h b/ios/chrome/browser/overlays/public/overlay_presentation_callback.h new file mode 100644 index 0000000..e30a632 --- /dev/null +++ b/ios/chrome/browser/overlays/public/overlay_presentation_callback.h
@@ -0,0 +1,15 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTATION_CALLBACK_H_ +#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTATION_CALLBACK_H_ + +#include "base/callback.h" + +// Overlay UI presented by OverlayPresenter::Delegate are provided with an +// OverlayPresentationCallback that is used to notify the presenter when +// requested overlay UI has finished being presented. +typedef base::OnceCallback<void()> OverlayPresentationCallback; + +#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTATION_CALLBACK_H_
diff --git a/ios/chrome/browser/overlays/public/overlay_presentation_context.h b/ios/chrome/browser/overlays/public/overlay_presentation_context.h index 4ac8c4b..f6342b4 100644 --- a/ios/chrome/browser/overlays/public/overlay_presentation_context.h +++ b/ios/chrome/browser/overlays/public/overlay_presentation_context.h
@@ -6,6 +6,7 @@ #define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTATION_CONTEXT_H_ #include "ios/chrome/browser/overlays/public/overlay_dismissal_callback.h" +#include "ios/chrome/browser/overlays/public/overlay_presentation_callback.h" class OverlayPresenter; class OverlayRequest; @@ -26,10 +27,12 @@ virtual bool IsActive() const = 0; // Called by |presenter| to show the overlay UI for |request|. - // |dismissal_callback| must be stored and called whenever the UI is finished - // being dismissed for user interaction, hiding, or cancellation. + // |presentation_callback| must be called when the UI is finished being + // presented. |dismissal_callback| must be stored and called whenever the UI + // is finished being dismissed for user interaction, hiding, or cancellation. virtual void ShowOverlayUI(OverlayPresenter* presenter, OverlayRequest* request, + OverlayPresentationCallback presentation_callback, OverlayDismissalCallback dismissal_callback) = 0; // Called by |presenter| to hide the overlay UI for |request|. Hidden
diff --git a/ios/chrome/browser/overlays/public/overlay_presenter_observer.h b/ios/chrome/browser/overlays/public/overlay_presenter_observer.h index e4bcf81..5c6f35e 100644 --- a/ios/chrome/browser/overlays/public/overlay_presenter_observer.h +++ b/ios/chrome/browser/overlays/public/overlay_presenter_observer.h
@@ -20,6 +20,11 @@ virtual void WillShowOverlay(OverlayPresenter* presenter, OverlayRequest* request) {} + // Called when |presenter| has finished showing the overlay UI for + // |request|. + virtual void DidShowOverlay(OverlayPresenter* presenter, + OverlayRequest* request) {} + // Called when |presenter| is finished dismissing its overlay UI. virtual void DidHideOverlay(OverlayPresenter* presenter, OverlayRequest* request) {}
diff --git a/ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h b/ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h new file mode 100644 index 0000000..d4a9067 --- /dev/null +++ b/ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h
@@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTER_OBSERVER_BRIDGE_H_ +#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTER_OBSERVER_BRIDGE_H_ + +#import <Foundation/Foundation.h> + +#include <string> + +#include "base/macros.h" +#include "ios/chrome/browser/overlays/public/overlay_presenter_observer.h" + +// Observes overlay UI presentation events from Objective-C. To use as an +// OverlayPresenterObserver, wrap in an OverlayPresenterObserverBridge. +@protocol OverlayPresenterObserving <NSObject> +@optional + +// Invoked by OverlayPresenterObserver::WillShowOverlay(). +- (void)overlayPresenter:(OverlayPresenter*)presenter + willShowOverlayForRequest:(OverlayRequest*)request; + +// Invoked by OverlayPresenterObserver::DidShowOverlay(). +- (void)overlayPresenter:(OverlayPresenter*)presenter + didShowOverlayForRequest:(OverlayRequest*)request; + +// Invoked by OverlayPresenterObserver::DidHideOverlay(). +- (void)overlayPresenter:(OverlayPresenter*)presenter + didHideOverlayForRequest:(OverlayRequest*)request; + +// Invoked by OverlayPresenterObserver::OverlayPresenterDestroyed(). +- (void)overlayPresenterDestroyed:(OverlayPresenter*)presenter; + +@end + +// C++ wrapper that forwards OverlayPresenterObserver callbacks to an Objective- +// C object conforming to OverlayPresenterObserving. +class OverlayPresenterObserverBridge : public OverlayPresenterObserver { + public: + // It it the responsibility of calling code to add/remove the instance + // from OverlayPresenter's observer list. + OverlayPresenterObserverBridge(id<OverlayPresenterObserving> observer); + ~OverlayPresenterObserverBridge() override; + + // OverlayPresenterObserver: + void WillShowOverlay(OverlayPresenter* presenter, + OverlayRequest* request) override; + void DidShowOverlay(OverlayPresenter* presenter, + OverlayRequest* request) override; + void DidHideOverlay(OverlayPresenter* presenter, + OverlayRequest* request) override; + void OverlayPresenterDestroyed(OverlayPresenter* presenter) override; + + private: + __weak id<OverlayPresenterObserving> observer_ = nil; + + DISALLOW_COPY_AND_ASSIGN(OverlayPresenterObserverBridge); +}; + +#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_OVERLAY_PRESENTER_OBSERVER_BRIDGE_H_
diff --git a/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.cc b/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.cc index 52ede06..550f77d 100644 --- a/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.cc +++ b/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.cc
@@ -14,25 +14,26 @@ FakeOverlayPresentationContext::PresentationState FakeOverlayPresentationContext::GetPresentationState(OverlayRequest* request) { - return presentation_states_[request]; + return states_[request].presentation_state; } void FakeOverlayPresentationContext::SimulateDismissalForRequest( OverlayRequest* request, OverlayDismissalReason reason) { - DCHECK_EQ(PresentationState::kPresented, presentation_states_[request]); + FakeUIState& state = states_[request]; + DCHECK_EQ(PresentationState::kPresented, state.presentation_state); switch (reason) { case OverlayDismissalReason::kUserInteraction: - presentation_states_[request] = PresentationState::kUserDismissed; + state.presentation_state = PresentationState::kUserDismissed; break; case OverlayDismissalReason::kHiding: - presentation_states_[request] = PresentationState::kHidden; + state.presentation_state = PresentationState::kHidden; break; case OverlayDismissalReason::kCancellation: - presentation_states_[request] = PresentationState::kCancelled; + state.presentation_state = PresentationState::kCancelled; break; } - std::move(overlay_callbacks_[request]).Run(reason); + std::move(state.dismissal_callback).Run(reason); } void FakeOverlayPresentationContext::SetIsActive(bool active) { @@ -65,9 +66,12 @@ void FakeOverlayPresentationContext::ShowOverlayUI( OverlayPresenter* presenter, OverlayRequest* request, + OverlayPresentationCallback presentation_callback, OverlayDismissalCallback dismissal_callback) { - presentation_states_[request] = PresentationState::kPresented; - overlay_callbacks_[request] = std::move(dismissal_callback); + FakeUIState& state = states_[request]; + state.presentation_state = PresentationState::kPresented; + state.presentation_callback = std::move(presentation_callback); + state.dismissal_callback = std::move(dismissal_callback); } void FakeOverlayPresentationContext::HideOverlayUI(OverlayPresenter* presenter, @@ -78,10 +82,14 @@ void FakeOverlayPresentationContext::CancelOverlayUI( OverlayPresenter* presenter, OverlayRequest* request) { - PresentationState& state = presentation_states_[request]; - if (state == PresentationState::kPresented) { + FakeUIState& state = states_[request]; + if (state.presentation_state == PresentationState::kPresented) { SimulateDismissalForRequest(request, OverlayDismissalReason::kCancellation); } else { - state = PresentationState::kCancelled; + state.presentation_state = PresentationState::kCancelled; } } + +FakeOverlayPresentationContext::FakeUIState::FakeUIState() = default; + +FakeOverlayPresentationContext::FakeUIState::~FakeUIState() = default;
diff --git a/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.h b/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.h index b159253..0806f99 100644 --- a/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.h +++ b/ios/chrome/browser/overlays/test/fake_overlay_presentation_context.h
@@ -46,6 +46,7 @@ bool IsActive() const override; void ShowOverlayUI(OverlayPresenter* presenter, OverlayRequest* request, + OverlayPresentationCallback presentation_callback, OverlayDismissalCallback dismissal_callback) override; void HideOverlayUI(OverlayPresenter* presenter, OverlayRequest* request) override; @@ -53,10 +54,18 @@ OverlayRequest* request) override; private: - // The presentation states for each OverlayRequest. - std::map<OverlayRequest*, PresentationState> presentation_states_; - // The callbacks for each OverlayRequest. - std::map<OverlayRequest*, OverlayDismissalCallback> overlay_callbacks_; + // Struct used to store state for the fake presentation context. + struct FakeUIState { + FakeUIState(); + ~FakeUIState(); + + PresentationState presentation_state = PresentationState::kNotPresented; + OverlayPresentationCallback presentation_callback; + OverlayDismissalCallback dismissal_callback; + }; + + // The UI states for each request. + std::map<OverlayRequest*, FakeUIState> states_; // Whether the context is active. bool active_ = true;
diff --git a/ios/chrome/browser/providers/chromium_browser_provider.h b/ios/chrome/browser/providers/chromium_browser_provider.h index f333e12..a80ca906 100644 --- a/ios/chrome/browser/providers/chromium_browser_provider.h +++ b/ios/chrome/browser/providers/chromium_browser_provider.h
@@ -18,6 +18,7 @@ void SetChromeIdentityServiceForTesting( std::unique_ptr<ios::ChromeIdentityService> service) override; ios::ChromeIdentityService* GetChromeIdentityService() override; + UITextField* CreateStyledTextField() const override NS_RETURNS_RETAINED; UITextField<TextFieldStyling>* CreateStyledTextField( CGRect frame) const override NS_RETURNS_RETAINED; VoiceSearchProvider* GetVoiceSearchProvider() const override;
diff --git a/ios/chrome/browser/providers/chromium_browser_provider.mm b/ios/chrome/browser/providers/chromium_browser_provider.mm index 62599c5..341a97c 100644 --- a/ios/chrome/browser/providers/chromium_browser_provider.mm +++ b/ios/chrome/browser/providers/chromium_browser_provider.mm
@@ -61,6 +61,10 @@ return chrome_identity_service_.get(); } +UITextField* ChromiumBrowserProvider::CreateStyledTextField() const { + return [[UITextField alloc] initWithFrame:CGRectZero]; +} + UITextField<TextFieldStyling>* ChromiumBrowserProvider::CreateStyledTextField( CGRect frame) const { return [[ChromiumStyledTextField alloc] initWithFrame:CGRectZero];
diff --git a/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm b/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm index b6bc375..d121a08e 100644 --- a/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm +++ b/ios/chrome/browser/ui/autofill/card_unmask_prompt_view_bridge.mm
@@ -361,10 +361,8 @@ } if ([self inputExpirationIsValid:item]) { - item.showDateInputError = NO; item.errorMessage = @""; } else { - item.showDateInputError = NO; item.errorMessage = l10n_util::GetNSString( IDS_AUTOFILL_CARD_UNMASK_INVALID_EXPIRATION_DATE); } @@ -436,7 +434,6 @@ _CVCItem.errorMessage = @""; _CVCItem.showDateInput = YES; _CVCItem.showNewCardButton = NO; - _CVCItem.showDateInputError = NO; _CVCItem.showCVCInputError = NO; [self reconfigureCellsForItems:@[ _CVCItem ]];
diff --git a/ios/chrome/browser/ui/autofill/cells/cvc_item.h b/ios/chrome/browser/ui/autofill/cells/cvc_item.h index d1bf8295..953a8f2 100644 --- a/ios/chrome/browser/ui/autofill/cells/cvc_item.h +++ b/ios/chrome/browser/ui/autofill/cells/cvc_item.h
@@ -10,15 +10,13 @@ #import "ios/chrome/browser/ui/collection_view/cells/collection_view_item.h" #import "ios/third_party/material_components_ios/src/components/CollectionCells/src/MaterialCollectionCells.h" -@protocol TextFieldStyling; - // Item corresponding to a CVCCell. @interface CVCItem : CollectionViewItem // The instructions text to display. @property(nonatomic, copy) NSString* instructionsText; -// The optioonal error message to display. +// The optional error message to display. @property(nonatomic, copy) NSString* errorMessage; // The month text appearing in the |monthInput| of the cell, if |showDateInput| @@ -38,9 +36,6 @@ // Whether the cell should show the "New Card?" button. @property(nonatomic, assign) BOOL showNewCardButton; -// Whether the date inputs contain erroneous data. -@property(nonatomic, assign) BOOL showDateInputError; - // Whether the CVC input contains erroneous data. @property(nonatomic, assign) BOOL showCVCInputError; @@ -65,14 +60,13 @@ @property(nonatomic, readonly, strong) UILabel* errorLabel; // The text field for entering the month. -@property(nonatomic, readonly, strong) - UITextField<TextFieldStyling>* monthInput; +@property(nonatomic, readonly, strong) UITextField* monthInput; // The text field for entering the year. -@property(nonatomic, readonly, strong) UITextField<TextFieldStyling>* yearInput; +@property(nonatomic, readonly, strong) UITextField* yearInput; // The text field for entering the CVC. -@property(nonatomic, readonly, strong) UITextField<TextFieldStyling>* CVCInput; +@property(nonatomic, readonly, strong) UITextField* CVCInput; // The image view to display the CVC image with the |CVCResourceID|. @property(nonatomic, readonly, strong) UIImageView* CVCImageView;
diff --git a/ios/chrome/browser/ui/autofill/cells/cvc_item.mm b/ios/chrome/browser/ui/autofill/cells/cvc_item.mm index a26e6c0..5311d77 100644 --- a/ios/chrome/browser/ui/autofill/cells/cvc_item.mm +++ b/ios/chrome/browser/ui/autofill/cells/cvc_item.mm
@@ -9,7 +9,6 @@ #import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#import "ios/public/provider/chrome/browser/ui/text_field_styling.h" #import "ios/third_party/material_components_ios/src/components/Palettes/src/MaterialPalettes.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ui/base/l10n/l10n_util.h" @@ -52,7 +51,6 @@ @synthesize CVCText = _CVCText; @synthesize showDateInput = _showDateInput; @synthesize showNewCardButton = _showNewCardButton; -@synthesize showDateInputError = _showDateInputError; @synthesize showCVCInputError = _showCVCInputError; @synthesize CVCImageResourceID = _CVCImageResourceID; @@ -80,10 +78,6 @@ cell.CVCContainerLeadingConstraintWithDate.active = self.showDateInput; cell.CVCContainerLeadingConstraintWithoutDate.active = !self.showDateInput; - [cell.monthInput setUseErrorStyling:self.showDateInputError]; - [cell.yearInput setUseErrorStyling:self.showDateInputError]; - [cell.CVCInput setUseErrorStyling:self.showDateInputError]; - cell.buttonForNewCard.hidden = !self.showNewCardButton; cell.CVCImageView.image = NativeImage(self.CVCImageResourceID); @@ -316,9 +310,6 @@ self.dateContainerView.hidden = YES; self.CVCContainerLeadingConstraintWithDate.active = NO; self.CVCContainerLeadingConstraintWithoutDate.active = YES; - [self.monthInput setUseErrorStyling:NO]; - [self.yearInput setUseErrorStyling:NO]; - [self.CVCInput setUseErrorStyling:NO]; self.buttonForNewCard.hidden = YES; self.CVCImageView.image = nil; }
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm index 973c133..97e17dd 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_edit_view_controller.mm
@@ -39,7 +39,6 @@ #import "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#import "ios/public/provider/chrome/browser/ui/text_field_styling.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/gfx/image/image.h" #include "url/gurl.h" @@ -79,10 +78,9 @@ const CGFloat kEstimatedTableSectionFooterHeight = 40; } // namespace -@interface BookmarkEditViewController ()<BookmarkFolderViewControllerDelegate, - BookmarkModelBridgeObserver, - BookmarkTextFieldItemDelegate, - TextFieldValidation> { +@interface BookmarkEditViewController () <BookmarkFolderViewControllerDelegate, + BookmarkModelBridgeObserver, + BookmarkTextFieldItemDelegate> { // Flag to ignore bookmark model changes notifications. BOOL _ignoresBookmarkModelChanges; @@ -499,17 +497,6 @@ return YES; } -#pragma mark - TextFieldValidation - -- (NSString*)validationErrorForTextField:(id<TextFieldStyling>)field { - [self updateSaveButtonState]; - if ([self inputURLIsValid]) { - return nil; - } else { - return l10n_util::GetNSString(IDS_IOS_BOOKMARK_URL_FIELD_VALIDATION_FAILED); - } -} - #pragma mark - UITableViewDataSource - (UITableViewCell*)tableView:(UITableView*)tableView
diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm index 3d8ad0b..d936060 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
@@ -31,7 +31,6 @@ #import "ios/chrome/browser/ui/table_view/table_view_navigation_controller_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #include "ios/chrome/browser/ui/util/ui_util.h" -#import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/earl_grey/accessibility_util.h" @@ -208,7 +207,7 @@ [BookmarksTestCase assertBookmarksWithTitle:bookmarkTitle expectedCount:1]; // Verify the star is lit. - if (!IsCompactWidth()) { + if (![ChromeEarlGrey isCompactWidth]) { [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel( l10n_util::GetNSString(IDS_TOOLTIP_STAR))] @@ -216,7 +215,7 @@ } // Open the BookmarkEditor. - if (IsCompactWidth()) { + if ([ChromeEarlGrey isCompactWidth]) { [ChromeEarlGreyUI openToolsMenu]; [[[EarlGrey selectElementWithMatcher:grey_allOf(grey_accessibilityID( @@ -242,7 +241,7 @@ [BookmarksTestCase assertBookmarksWithTitle:bookmarkTitle expectedCount:0]; // Verify the the page is no longer bookmarked. - if (IsCompactWidth()) { + if ([ChromeEarlGrey isCompactWidth]) { [ChromeEarlGreyUI openToolsMenu]; [[[EarlGrey selectElementWithMatcher:grey_allOf(grey_accessibilityID( @@ -350,7 +349,7 @@ performAction:grey_tap()]; // Edit the bookmark. - if (!IsCompactWidth()) { + if (![ChromeEarlGrey isCompactWidth]) { [[EarlGrey selectElementWithMatcher:StarButton()] performAction:grey_tap()]; } else { [ChromeEarlGreyUI openToolsMenu]; @@ -1750,7 +1749,7 @@ // grey_swipeFastInDirectionWithStartPoint doesn't work either and it might // fail on devices. Disabling this test under these conditions on the // meantime. - if (!IsCompactWidth()) { + if (![ChromeEarlGrey isCompactWidth]) { EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad."); } @@ -1800,7 +1799,7 @@ // grey_swipeFastInDirectionWithStartPoint doesn't work either and it might // fail on devices. Disabling this test under these conditions on the // meantime. - if (!IsCompactWidth()) { + if (![ChromeEarlGrey isCompactWidth]) { EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad on iOS11."); } @@ -3425,7 +3424,7 @@ // Dismiss the context menu. On non compact width tap the Bookmarks TableView // to dismiss, since there might not be a cancel button. - if (IsCompactWidth()) { + if ([ChromeEarlGrey isCompactWidth]) { [[EarlGrey selectElementWithMatcher:ButtonWithAccessibilityLabelId(IDS_CANCEL)] performAction:grey_tap()]; @@ -4456,7 +4455,7 @@ // grey_swipeFastInDirectionWithStartPoint doesn't work either and it might // fail on devices. Disabling this test under these conditions on the // meantime. - if (!IsCompactWidth()) { + if (![ChromeEarlGrey isCompactWidth]) { EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad on iOS11."); } @@ -4484,7 +4483,7 @@ // grey_swipeFastInDirectionWithStartPoint doesn't work either and it might // fail on devices. Disabling this test under these conditions on the // meantime. - if (!IsCompactWidth()) { + if (![ChromeEarlGrey isCompactWidth]) { EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad on iOS11."); }
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h index 87cae9ad..69d5a17 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.h
@@ -10,7 +10,6 @@ #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h" @class BookmarkTextFieldItem; -@protocol TextFieldStyling; // Delegates the cell's text field's events. @protocol BookmarkTextFieldItemDelegate<UITextFieldDelegate>
diff --git a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm index cf9729b..3c9d893 100644 --- a/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm +++ b/ios/chrome/browser/ui/bookmarks/cells/bookmark_text_field_item.mm
@@ -13,7 +13,6 @@ #import "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" -#import "ios/public/provider/chrome/browser/ui/text_field_styling.h" #include "ui/base/l10n/l10n_util_mac.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index c7b76ab..547fb50 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -134,7 +134,6 @@ "//ios/chrome/browser/ui/overscroll_actions", "//ios/chrome/browser/ui/toolbar/buttons", "//ios/chrome/browser/ui/toolbar/public", - "//ios/chrome/browser/ui/toolbar/resources:tab_toolbar_shadow_color", "//ios/chrome/browser/ui/util:util", "//ios/chrome/common/colors", "//ios/chrome/common/favicon",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm index 7888b6ad..be312777 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
@@ -252,8 +252,7 @@ DCHECK(searchField.superview == self); self.separator = [[UIView alloc] init]; - self.separator.backgroundColor = - [UIColor colorNamed:@"tab_toolbar_shadow_color"]; + self.separator.backgroundColor = [UIColor colorNamed:kToolbarShadowColor]; self.separator.alpha = 0; self.separator.translatesAutoresizingMaskIntoConstraints = NO; [searchField addSubview:self.separator];
diff --git a/ios/chrome/browser/ui/history/history_entry_item.mm b/ios/chrome/browser/ui/history/history_entry_item.mm index bc3d7ac..33f38d0 100644 --- a/ios/chrome/browser/ui/history/history_entry_item.mm +++ b/ios/chrome/browser/ui/history/history_entry_item.mm
@@ -56,10 +56,6 @@ cell.titleLabel.text = self.text; cell.URLLabel.text = self.detailText; cell.metadataLabel.text = self.timeText; - cell.faviconContainerView.backgroundColor = styler.tableViewBackgroundColor; - cell.titleLabel.backgroundColor = styler.tableViewBackgroundColor; - cell.URLLabel.backgroundColor = styler.tableViewBackgroundColor; - cell.metadataLabel.backgroundColor = styler.tableViewBackgroundColor; cell.isAccessibilityElement = YES; cell.accessibilityCustomActions = self.accessibilityActions; [cell configureUILayout];
diff --git a/ios/chrome/browser/ui/location_bar/BUILD.gn b/ios/chrome/browser/ui/location_bar/BUILD.gn index e6a3946c..9a23ed2 100644 --- a/ios/chrome/browser/ui/location_bar/BUILD.gn +++ b/ios/chrome/browser/ui/location_bar/BUILD.gn
@@ -60,8 +60,6 @@ "//ios/chrome/browser/ui/omnibox/popup", "//ios/chrome/browser/ui/orchestrator:orchestrator", "//ios/chrome/browser/ui/toolbar/buttons", - "//ios/chrome/browser/ui/toolbar/buttons/resources:tab_toolbar_button_color", - "//ios/chrome/browser/ui/toolbar/buttons/resources:tab_toolbar_button_color_incognito", "//ios/chrome/browser/ui/toolbar/keyboard_assist:keyboard_assist", "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/public:feature_flags",
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_consumer.h b/ios/chrome/browser/ui/location_bar/location_bar_consumer.h index 2df04ea..56a52771 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_consumer.h +++ b/ios/chrome/browser/ui/location_bar/location_bar_consumer.h
@@ -34,15 +34,6 @@ // changes. (This is usually when the default search engine changes). - (void)updateSearchByImageSupported:(BOOL)searchByImageSupported; -// Notifies the consumer to display or hide the Infobar badge. -// TODO(crbug.com/935804): This method is currently only being used in the -// Infobar redesign. -- (void)displayInfobarBadge:(BOOL)display type:(InfobarType)infobarType; - -// Notifies the consumer that the InfobarBadge active state has changed. -// TODO(crbug.com/935804): This method is currently only being used in the -// Infobar redesign. -- (void)activeInfobarBadge:(BOOL)active; @end
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm index b5bbac2..b87a0ac 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -22,6 +22,7 @@ #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #include "ios/chrome/browser/search_engines/template_url_service_factory.h" #import "ios/chrome/browser/ui/badges/badge_mediator.h" +#import "ios/chrome/browser/ui/badges/badge_view_controller.h" #include "ios/chrome/browser/ui/commands/browser_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/load_query_commands.h" @@ -163,8 +164,13 @@ // Create BadgeMediator and set the viewController as its consumer. if (IsInfobarUIRebootEnabled()) { + BadgeViewController* badgeViewController = + [[BadgeViewController alloc] init]; + [self.viewController addChildViewController:badgeViewController]; + [self.viewController setBadgeView:badgeViewController.view]; + [badgeViewController didMoveToParentViewController:self.viewController]; self.badgeMediator = - [[BadgeMediator alloc] initWithConsumer:self.viewController + [[BadgeMediator alloc] initWithConsumer:badgeViewController webStateList:self.webStateList]; } @@ -394,21 +400,6 @@ self.viewController.searchByImageEnabled = searchByImageSupported; } -- (void)displayInfobarBadge:(BOOL)display type:(InfobarType)infobarType { - InfobarMetricsRecorder* metricsRecorder; - // If the Badge will be displayed create a metrics recorder to log its - // interactions, if its hidden metrics recorder should be nil. - if (display) - metricsRecorder = [[InfobarMetricsRecorder alloc] initWithType:infobarType]; - - [self.viewController displayInfobarButton:display - metricsRecorder:metricsRecorder]; -} - -- (void)activeInfobarBadge:(BOOL)active { - [self.viewController setInfobarButtonStyleActive:active]; -} - #pragma mark - private // Returns a dictionary with variation headers for qualified URLs. Can be empty.
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h index a2ed0a3a..1a4832e 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h +++ b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.h
@@ -40,9 +40,9 @@ // Sets the location label's text and styles it as if it were placeholder text. - (void)setLocationLabelPlaceholderText:(NSString*)string; -// Displays the location InfobarBadgeButton if |display| is YES, hides it if +// Displays the location badge view if |display| is YES, hides it if // |display| is NO. Will animate change if |animated| is YES. -- (void)displayBadge:(BOOL)display animated:(BOOL)animated; +- (void)displayBadgeView:(BOOL)display animated:(BOOL)animated; // Toggles |enabled| state of the trailing button and updates accessibility // appropriately. @@ -52,12 +52,9 @@ @property(nonatomic, strong) UIButton* locationButton; // The label displaying the current location URL. @property(nonatomic, strong) UILabel* locationLabel; -// The InfobarBadgeButton displayed in the leading corner of the view. -// Call displayBadge:animated: in this class instead of InfobarBadgeButton's -// directly. -// TODO(crbug.com/935804): This button is currently only being used in the -// Infobar redesign. -@property(nonatomic, strong) InfobarBadgeButton* leadingButton; +// The view displaying badges in the leading corner of the view. +// TODO(crbug.com/991241): Pass into init as parameter. +@property(nonatomic, strong) UIView* badgeView; // The button displayed in the trailing corner of the view, i.e. share button. @property(nonatomic, strong) UIButton* trailingButton; // The string that describes the current security level. Used for a11y.
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm index cd0452aa..0f47745 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_steady_view.mm
@@ -24,7 +24,6 @@ // Length of the trailing button side. const CGFloat kButtonSize = 24; - // Space between the location icon and the location label. const CGFloat kLocationImageToLabelSpacing = -4.0; // Minimal horizontal padding between the leading edge of the location bar and @@ -33,7 +32,8 @@ // Trailing space between the trailing button and the trailing edge of the // location bar. const CGFloat kButtonTrailingSpacing = 10; - +// Duration of display and hide animation of the badge view, in seconds. +const CGFloat kbadgeViewAnimationDuration = 0.2; } // namespace @interface LocationBarSteadyView () @@ -45,6 +45,11 @@ // view. @property(nonatomic, strong) UIView* locationContainerView; +// Leading constraint for locationContainerView when there is no BadgeView to +// its left. +@property(nonatomic, strong) + NSLayoutConstraint* locationContainerViewLeadingAnchorConstraint; + // Constraints to hide the location image view. @property(nonatomic, strong) NSArray<NSLayoutConstraint*>* hideLocationImageConstraints; @@ -68,7 +73,7 @@ scheme.fontColor = [UIColor colorNamed:kTextPrimaryColor]; scheme.placeholderColor = [UIColor colorNamed:kTextfieldPlaceholderColor]; - scheme.trailingButtonColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; + scheme.trailingButtonColor = [UIColor colorNamed:kToolbarButtonColor]; return scheme; } @@ -82,8 +87,7 @@ // TODO(crbug.com/981889): Clean up after iOS 12 support is dropped. scheme.fontColor = [UIColor colorNamed:kTextPrimaryDarkColor]; scheme.placeholderColor = [UIColor colorNamed:kTextfieldPlaceholderDarkColor]; - scheme.trailingButtonColor = - [UIColor colorNamed:@"tab_toolbar_button_color_incognito"]; + scheme.trailingButtonColor = [UIColor colorNamed:kToolbarButtonDarkColor]; return scheme; } @@ -198,6 +202,11 @@ constraintEqualToAnchor:self.centerXAnchor]; centerX.priority = UILayoutPriorityDefaultHigh; + _locationContainerViewLeadingAnchorConstraint = + [_locationContainerView.leadingAnchor + constraintGreaterThanOrEqualToAnchor:self.leadingAnchor + constant:kLocationBarLeadingPadding]; + // Setup and activate constraints. [NSLayoutConstraint activateConstraints:@[ [_trailingButton.centerYAnchor @@ -213,44 +222,17 @@ constraintEqualToAnchor:self.trailingAnchor constant:-kButtonTrailingSpacing], centerX, + _locationContainerViewLeadingAnchorConstraint, ]]; - - if (IsInfobarUIRebootEnabled()) { - // Setup leading button. - _leadingButton = [InfobarBadgeButton buttonWithType:UIButtonTypeSystem]; - _leadingButton.translatesAutoresizingMaskIntoConstraints = NO; - [_locationButton addSubview:_leadingButton]; - - // Setup and activate the leading button constraints. - [NSLayoutConstraint activateConstraints:@[ - [_leadingButton.widthAnchor - constraintEqualToAnchor:_leadingButton.heightAnchor], - [_leadingButton.topAnchor constraintEqualToAnchor:self.topAnchor], - [_leadingButton.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], - [_leadingButton.leadingAnchor - constraintEqualToAnchor:self.leadingAnchor], - [_leadingButton.trailingAnchor - constraintLessThanOrEqualToAnchor:_locationContainerView - .leadingAnchor], - [_leadingButton.centerYAnchor - constraintEqualToAnchor:self.centerYAnchor], - ]]; - } else { - // Since there is no leading button, |locationContainerView|'s - // leadingAnchor will be pinned to |self|. - [NSLayoutConstraint activateConstraints:@[ - [_locationContainerView.leadingAnchor - constraintGreaterThanOrEqualToAnchor:self.leadingAnchor - constant:kLocationBarLeadingPadding], - ]]; - } } // Setup accessibility. _trailingButton.isAccessibilityElement = YES; - if (IsInfobarUIRebootEnabled()) { - _leadingButton.isAccessibilityElement = YES; - _leadingButton.accessibilityLabel = + if (self.badgeView) { + self.badgeView.isAccessibilityElement = YES; + // TODO(crbug.com/989233): This needs to reflect the currently displayed + // badge. + self.badgeView.accessibilityLabel = l10n_util::GetNSString(IDS_IOS_INFOBAR_BADGES_PASSWORD_HINT); } _locationButton.isAccessibilityElement = YES; @@ -325,17 +307,46 @@ [self updateAccessibility]; } -- (void)displayBadge:(BOOL)display animated:(BOOL)animated { +- (void)setBadgeView:(UIView*)badgeView { + BOOL hadBadgeView = _badgeView != nil; + _badgeView = badgeView; + if (!hadBadgeView && badgeView) { + _badgeView.translatesAutoresizingMaskIntoConstraints = NO; + [self.locationButton addSubview:_badgeView]; + + [NSLayoutConstraint deactivateConstraints:@[ + self.locationContainerViewLeadingAnchorConstraint + ]]; + [NSLayoutConstraint activateConstraints:@[ + [_badgeView.topAnchor constraintEqualToAnchor:self.topAnchor], + [_badgeView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], + [_badgeView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor], + [_badgeView.trailingAnchor + constraintLessThanOrEqualToAnchor:self.locationContainerView + .leadingAnchor], + ]]; + } +} + +- (void)displayBadgeView:(BOOL)display animated:(BOOL)animated { if (display) { // Adding InfobarBadge button as an accessibility element behind location // label. Thus, there should be at least one object alreading in // |accessibleElements|. DCHECK([self.accessibleElements count] > 0); - [self.accessibleElements insertObject:self.leadingButton atIndex:1]; + [self.accessibleElements insertObject:self.badgeView atIndex:1]; } else { - [self.accessibleElements removeObject:self.leadingButton]; + [self.accessibleElements removeObject:self.badgeView]; } - [self.leadingButton displayBadge:display animated:animated]; + void (^changeHiddenState)() = ^{ + self.badgeView.hidden = !display; + }; + if (animated) { + [UIView animateWithDuration:kbadgeViewAnimationDuration + animations:changeHiddenState]; + } else { + changeHiddenState(); + } } - (void)enableTrailingButton:(BOOL)enabled {
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h index 31db378..8c54c86 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h +++ b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.h
@@ -36,12 +36,16 @@ // the omnibox textfield is displayed; in the non-editing state, the current // location is displayed. @interface LocationBarViewController - : UIViewController <BadgeConsumer, FullscreenUIElement, LocationBarAnimatee> + : UIViewController <FullscreenUIElement, LocationBarAnimatee> // Sets the edit view to use in the editing state. This must be set before the // view of this view controller is initialized. This must only be called once. - (void)setEditView:(UIView*)editView; +// Sets the badge view to display badges. This must be set before the +// view of this view controller is initialized. This must only be called once. +- (void)setBadgeView:(UIView*)badgeView; + @property(nonatomic, assign) BOOL incognito; // The dispatcher for the share button, voice search, and long press actions. @@ -77,16 +81,6 @@ - (void)updateForNTP:(BOOL)isNTP; // Sets |enabled| of the share button. - (void)setShareButtonEnabled:(BOOL)enabled; -// Displays or hides the InfobarButton. |metricsRecorder| can be nil. -// TODO(crbug.com/935804): This method is currently only being used in the -// Infobar redesign. -- (void)displayInfobarButton:(BOOL)display - metricsRecorder:(InfobarMetricsRecorder*)metricsRecorder; -// If |active| is YES applies the active styling to the InfobarButton, if NO it -// removes it. -// TODO(crbug.com/935804): This method is currently only being used in the -// Infobar redesign. -- (void)setInfobarButtonStyleActive:(BOOL)active; // Displays the voice search button instead of the share button in steady state, // and adds the voice search button to the empty textfield.
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm index c010f1a..0d6328b 100644 --- a/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm +++ b/ios/chrome/browser/ui/location_bar/location_bar_view_controller.mm
@@ -46,6 +46,9 @@ // The injected edit view. @property(nonatomic, strong) UIView* editView; +// The injected badge view. +@property(nonatomic, strong) UIView* badgeView; + // The view that displays current location when the omnibox is not focused. @property(nonatomic, strong) LocationBarSteadyView* locationBarSteadyView; @@ -61,17 +64,6 @@ // icon (in iPad multitasking). @property(nonatomic, assign) BOOL shareButtonEnabled; -// Keeps the status of the leading button of the location bar steady view. Used -// to preserve leading button visibility during animations. -@property(nonatomic, assign) BOOL shouldShowLeadingButton; - -// Used to build and record Infobar metrics. -@property(nonatomic, strong) InfobarMetricsRecorder* infobarMetricsRecorder; - -// Whether the InfobarBadge is active or not. -// TODO(crbug.com/961343): Move this into a future BadgeContainer. -@property(nonatomic, assign) BOOL activeBadge; - // Starts voice search, updating the NamedGuide to be constrained to the // trailing button. - (void)startVoiceSearch; @@ -100,17 +92,6 @@ self = [super init]; if (self) { _locationBarSteadyView = [[LocationBarSteadyView alloc] init]; - - [_locationBarSteadyView.locationButton - addTarget:self - action:@selector(locationBarSteadyViewTapped) - forControlEvents:UIControlEventTouchUpInside]; - - UILongPressGestureRecognizer* recognizer = - [[UILongPressGestureRecognizer alloc] - initWithTarget:self - action:@selector(showLongPressMenu:)]; - [_locationBarSteadyView.locationButton addGestureRecognizer:recognizer]; } return self; } @@ -120,6 +101,11 @@ _editView = editView; } +- (void)setBadgeView:(UIView*)badgeView { + DCHECK(!self.badgeView); + _badgeView = badgeView; +} + - (void)switchToEditing:(BOOL)editing { self.editView.hidden = !editing; self.locationBarSteadyView.hidden = editing; @@ -177,6 +163,22 @@ - (void)viewDidLoad { [super viewDidLoad]; + if (IsInfobarUIRebootEnabled()) { + DCHECK(self.badgeView) << "The badge view must be set at this point"; + self.locationBarSteadyView.badgeView = self.badgeView; + } + + [_locationBarSteadyView.locationButton + addTarget:self + action:@selector(locationBarSteadyViewTapped) + forControlEvents:UIControlEventTouchUpInside]; + + UILongPressGestureRecognizer* recognizer = + [[UILongPressGestureRecognizer alloc] + initWithTarget:self + action:@selector(showLongPressMenu:)]; + [_locationBarSteadyView.locationButton addGestureRecognizer:recognizer]; + DCHECK(self.editView) << "The edit view must be set at this point"; [self.view addSubview:self.editView]; @@ -188,10 +190,6 @@ AddSameConstraints(self.locationBarSteadyView, self.view); [self switchToEditing:NO]; - - if (IsInfobarUIRebootEnabled()) { - [self updateInfobarButton]; - } } - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { @@ -206,7 +204,7 @@ CGFloat scaleValue = 0.79 + 0.21 * progress; self.locationBarSteadyView.trailingButton.alpha = alphaValue; if (IsInfobarUIRebootEnabled()) { - self.locationBarSteadyView.leadingButton.alpha = alphaValue; + self.locationBarSteadyView.badgeView.alpha = alphaValue; } self.locationBarSteadyView.transform = CGAffineTransformMakeScale(scaleValue, scaleValue); @@ -259,13 +257,6 @@ } } -- (void)displayInfobarButton:(BOOL)display - metricsRecorder:(InfobarMetricsRecorder*)metricsRecorder { - self.infobarMetricsRecorder = metricsRecorder; - self.shouldShowLeadingButton = display; - [self.locationBarSteadyView displayBadge:display animated:YES]; -} - #pragma mark - LocationBarAnimatee - (void)offsetEditViewToMatchSteadyView { @@ -296,13 +287,16 @@ self.locationBarSteadyView.alpha = hidden ? 0 : 1; } -- (void)hideSteadyViewLeadingButton { - [self.locationBarSteadyView displayBadge:NO animated:NO]; +- (void)hideSteadyViewBadgeView { + if (IsInfobarUIRebootEnabled()) { + [self.locationBarSteadyView displayBadgeView:NO animated:NO]; + } } -- (void)showSteadyViewLeadingButtonIfNeeded { - [self.locationBarSteadyView displayBadge:self.shouldShowLeadingButton - animated:NO]; +- (void)showSteadyViewBadgeView { + if (IsInfobarUIRebootEnabled()) { + [self.locationBarSteadyView displayBadgeView:YES animated:NO]; + } } - (void)setEditViewFaded:(BOOL)hidden { @@ -456,70 +450,6 @@ base::RecordAction(base::UserMetricsAction("MobileToolbarShareMenu")); } -// TODO(crbug.com/935804): Create constants variables for the magic numbers -// being used here if/when this stops being temporary. -- (void)updateInfobarButton { - DCHECK(IsInfobarUIRebootEnabled()); - - [self.locationBarSteadyView.leadingButton - addTarget:self - action:@selector(displayModalInfobar) - forControlEvents:UIControlEventTouchUpInside]; - // Set as hidden as it should only be shown by |displayInfobarButton:| - [self.locationBarSteadyView.leadingButton displayBadge:NO animated:NO]; -} - -- (void)displayModalInfobar { - MobileMessagesBadgeState state; - if (self.activeBadge) { - state = MobileMessagesBadgeState::Active; - base::RecordAction( - base::UserMetricsAction("MobileMessagesBadgeAcceptedTapped")); - } else { - state = MobileMessagesBadgeState::Inactive; - base::RecordAction( - base::UserMetricsAction("MobileMessagesBadgeNonAcceptedTapped")); - } - [self.infobarMetricsRecorder recordBadgeTappedInState:state]; - [self.dispatcher displayModalInfobar]; -} - -- (void)setInfobarButtonStyleActive:(BOOL)active { - self.activeBadge = active; - [self.locationBarSteadyView.leadingButton setActive:active animated:YES]; -} - -#pragma mark - BadgeConsumer - -- (void)setupWithBadges:(NSArray*)badges { - BOOL hasBadge = badges.count > 0; - if (hasBadge) { - id<BadgeItem> firstBadge = badges[0]; - BOOL isAccepted = firstBadge.isAccepted; - self.activeBadge = isAccepted; - [self.locationBarSteadyView.leadingButton setActive:isAccepted animated:NO]; - } - [self.locationBarSteadyView.leadingButton displayBadge:hasBadge animated:NO]; - self.shouldShowLeadingButton = hasBadge; -} - -- (void)addBadge:(id<BadgeItem>)badgeItem { - self.activeBadge = badgeItem.isAccepted; - [self.locationBarSteadyView.leadingButton setActive:badgeItem.isAccepted - animated:NO]; - [self.locationBarSteadyView.leadingButton displayBadge:YES animated:YES]; - self.shouldShowLeadingButton = YES; -} - -- (void)removeBadge:(id<BadgeItem>)badgeItem { - [self.locationBarSteadyView.leadingButton displayBadge:NO animated:NO]; - self.shouldShowLeadingButton = NO; -} - -- (void)updateBadge:(id<BadgeItem>)badgeItem { - [self.locationBarSteadyView.leadingButton setActive:badgeItem.isAccepted - animated:YES]; -} #pragma mark - UIMenu
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn index 3597527..f416ce8 100644 --- a/ios/chrome/browser/ui/omnibox/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -142,8 +142,6 @@ "//ios/chrome/browser/ui/location_bar:constants", "//ios/chrome/browser/ui/omnibox/popup", "//ios/chrome/browser/ui/orchestrator:orchestrator", - "//ios/chrome/browser/ui/toolbar/buttons/resources:tab_toolbar_button_color", - "//ios/chrome/browser/ui/toolbar/buttons/resources:tab_toolbar_button_color_incognito", "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", @@ -188,7 +186,6 @@ "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/content_suggestions:content_suggestions_constant", "//ios/chrome/browser/ui/omnibox/popup:popup_ui", - "//ios/chrome/browser/ui/util", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/testing/earl_grey:earl_grey_support",
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm index 754eb31..730a1a8 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_egtest.mm
@@ -9,7 +9,6 @@ #include "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_row.h" -#import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" @@ -98,7 +97,7 @@ - (void)testTrailingButton { [self openPage1]; - if (IsCompactWidth()) { + if ([ChromeEarlGrey isCompactWidth]) { [[EarlGrey selectElementWithMatcher:chrome_test_util::ShareButton()] assertWithMatcher:grey_sufficientlyVisible()]; }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm index 26880d9..c260073 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_controller.mm
@@ -68,12 +68,12 @@ UIColor* iconTintColor; if (base::FeatureList::IsEnabled(kNewOmniboxPopupLayout)) { iconTintColor = color::IncognitoDynamicColor( - self.incognito, [UIColor colorNamed:@"tab_toolbar_button_color"], - [UIColor colorNamed:@"tab_toolbar_button_color_incognito"]); + self.incognito, [UIColor colorNamed:kToolbarButtonColor], + [UIColor colorNamed:kToolbarButtonDarkColor]); } else { iconTintColor = color::IncognitoDynamicColor( - self.incognito, [UIColor colorNamed:@"tab_toolbar_button_color"], - [UIColor colorNamed:@"tab_toolbar_button_color_incognito"]); + self.incognito, [UIColor colorNamed:kToolbarButtonColor], + [UIColor colorNamed:kToolbarButtonDarkColor]); } self.view = [[OmniboxContainerView alloc]
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn index 2f9fc91..c9950ff7d 100644 --- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn +++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -34,9 +34,11 @@ "//ios/chrome/browser/ui/omnibox:omnibox_util", "//ios/chrome/browser/ui/omnibox/popup/shortcuts", "//ios/chrome/browser/ui/toolbar/buttons", + "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/public:feature_flags", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/web_state_list:web_state_list", + "//ios/chrome/common/colors", "//ios/chrome/common/favicon", "//ios/chrome/common/ui_util", "//ios/web/public:public",
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm index 09de7d6..21b2287 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -6,11 +6,14 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" #import "ios/chrome/browser/ui/toolbar/public/features.h" +#import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/util/named_guide.h" #include "ios/chrome/browser/ui/util/ui_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #include "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ios/chrome/grit/ios_theme_resources.h" +#import "ui/gfx/ios/uikit_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -27,6 +30,9 @@ @property(nonatomic, weak) id<OmniboxPopupPresenterDelegate> delegate; @property(nonatomic, weak) UIViewController* viewController; @property(nonatomic, strong) UIView* popupContainerView; +// Separator for the bottom edge of the popup on iPad. +@property(nonatomic, strong) UIView* bottomSeparator; + @end @implementation OmniboxPopupPresenter @@ -65,6 +71,26 @@ _popupContainerView.translatesAutoresizingMaskIntoConstraints = NO; viewController.view.translatesAutoresizingMaskIntoConstraints = NO; AddSameConstraints(viewController.view, _popupContainerView); + + // Add bottom separator. This will only be visible on iPad where + // the omnibox doesn't fill the whole screen. + _bottomSeparator = [[UIView alloc] initWithFrame:CGRectZero]; + _bottomSeparator.translatesAutoresizingMaskIntoConstraints = NO; + _bottomSeparator.backgroundColor = [UIColor colorNamed:kToolbarShadowColor]; + + [_popupContainerView addSubview:self.bottomSeparator]; + CGFloat separatorHeight = + ui::AlignValueToUpperPixel(kToolbarSeparatorHeight); + [NSLayoutConstraint activateConstraints:@[ + [self.bottomSeparator.heightAnchor + constraintEqualToConstant:separatorHeight], + [self.bottomSeparator.leadingAnchor + constraintEqualToAnchor:_popupContainerView.leadingAnchor], + [self.bottomSeparator.trailingAnchor + constraintEqualToAnchor:_popupContainerView.trailingAnchor], + [self.bottomSeparator.topAnchor + constraintEqualToAnchor:_popupContainerView.bottomAnchor], + ]]; } return self; } @@ -78,6 +104,7 @@ // popup view. if (!IsIPadIdiom()) { self.bottomConstraint.active = NO; + self.bottomSeparator.hidden = YES; } [self.viewController willMoveToParentViewController:nil]; @@ -99,6 +126,7 @@ if (!IsIPadIdiom()) { self.bottomConstraint.active = YES; + self.bottomSeparator.hidden = NO; } self.open = YES;
diff --git a/ios/chrome/browser/ui/orchestrator/location_bar_animatee.h b/ios/chrome/browser/ui/orchestrator/location_bar_animatee.h index c276d9b..78edcfd 100644 --- a/ios/chrome/browser/ui/orchestrator/location_bar_animatee.h +++ b/ios/chrome/browser/ui/orchestrator/location_bar_animatee.h
@@ -25,11 +25,10 @@ // See comment for -resetEditViewOffsetAndOffsetSteadyViewToMatch. - (void)resetSteadyViewOffsetAndOffsetEditViewToMatch; -// Hides leading button for steady view. -- (void)hideSteadyViewLeadingButton; -// Call this after calling -hideSteadyViewLeadingButton. Restores the displayed -// state of the leading button of the steady view. -- (void)showSteadyViewLeadingButtonIfNeeded; +// Hides badge view for steady view. +- (void)hideSteadyViewBadgeView; +// Displays the badge view of the steady view. +- (void)showSteadyViewBadgeView; - (void)setSteadyViewFaded:(BOOL)hidden; - (void)setEditViewFaded:(BOOL)hidden;
diff --git a/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm b/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm index 3954161a..294453eb 100644 --- a/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm +++ b/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm
@@ -87,10 +87,10 @@ if (animated) { // Prepare for animation. [self.locationBarAnimatee offsetEditViewToMatchSteadyView]; - // Hide leading button before the transform regardless of current displayed + // Hide badge view before the transform regardless of current displayed // state to prevent it from being visible outside of the location bar as the // steadView moves outside to the leading side of the location bar. - [self.locationBarAnimatee hideSteadyViewLeadingButton]; + [self.locationBarAnimatee hideSteadyViewBadgeView]; // Make edit view transparent, but not hidden. [self.locationBarAnimatee setEditViewHidden:NO]; [self.locationBarAnimatee setEditViewFaded:YES]; @@ -160,8 +160,7 @@ void (^cleanup)() = ^{ [self.locationBarAnimatee setEditViewHidden:YES]; [self.locationBarAnimatee setSteadyViewHidden:NO]; - // Restore the leading button to the original displayed state. - [self.locationBarAnimatee showSteadyViewLeadingButtonIfNeeded]; + [self.locationBarAnimatee showSteadyViewBadgeView]; [self.locationBarAnimatee resetTransforms]; [self.locationBarAnimatee setSteadyViewFaded:NO]; [self.editViewAnimatee setLeadingIconFaded:NO];
diff --git a/ios/chrome/browser/ui/overlays/BUILD.gn b/ios/chrome/browser/ui/overlays/BUILD.gn index c729e88..ea40159 100644 --- a/ios/chrome/browser/ui/overlays/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/BUILD.gn
@@ -53,7 +53,7 @@ sources = [ "overlay_request_coordinator.h", "overlay_request_coordinator.mm", - "overlay_ui_dismissal_delegate.h", + "overlay_request_coordinator_delegate.h", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.h b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.h index ccc7285..9cb45b2 100644 --- a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.h +++ b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.h
@@ -10,7 +10,7 @@ #include "ios/chrome/browser/overlays/public/overlay_modality.h" class Browser; -class OverlayUIDismissalDelegate; +class OverlayRequestCoordinatorDelegate; @class OverlayRequestCoordinator; class OverlayRequest; @@ -29,7 +29,7 @@ // Creates a coordinator to show |request|'s overlay UI. - (OverlayRequestCoordinator*) newCoordinatorForRequest:(OverlayRequest*)request - dismissalDelegate:(OverlayUIDismissalDelegate*)dismissalDelegate + delegate:(OverlayRequestCoordinatorDelegate*)delegate baseViewController:(UIViewController*)baseViewController; @end
diff --git a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm index df9a5ad3..f44c089 100644 --- a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm +++ b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm
@@ -40,16 +40,17 @@ - (OverlayRequestCoordinator*) newCoordinatorForRequest:(OverlayRequest*)request - dismissalDelegate:(OverlayUIDismissalDelegate*)dismissalDelegate + delegate:(OverlayRequestCoordinatorDelegate*)delegate baseViewController:(UIViewController*)baseViewController { - for (Class coordinatorClass in self - .supportedOverlayRequestCoordinatorClasses) { + NSArray<Class>* supportedClasses = + self.supportedOverlayRequestCoordinatorClasses; + for (Class coordinatorClass in supportedClasses) { if ([coordinatorClass supportsRequest:request]) { return [[coordinatorClass alloc] initWithBaseViewController:baseViewController browser:self.browser request:request - dismissalDelegate:dismissalDelegate]; + delegate:delegate]; } } NOTREACHED() << "Received unsupported request type.";
diff --git a/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.h b/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.h index 041c4b9..5a1a461 100644 --- a/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.h +++ b/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.h
@@ -12,8 +12,8 @@ #import "ios/chrome/browser/overlays/public/overlay_presentation_context.h" #import "ios/chrome/browser/overlays/public/overlay_user_data.h" #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/ui/overlays/overlay_request_ui_state.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" @class OverlayRequestCoordinatorFactory; @class OverlayContainerCoordinator; @@ -62,6 +62,7 @@ bool IsActive() const override; void ShowOverlayUI(OverlayPresenter* presenter, OverlayRequest* request, + OverlayPresentationCallback presentation_callback, OverlayDismissalCallback dismissal_callback) override; void HideOverlayUI(OverlayPresenter* presenter, OverlayRequest* request) override; @@ -102,13 +103,15 @@ }; // Helper object that listens for UI dismissal events. - class OverlayDismissalHelper : public OverlayUIDismissalDelegate { + class OverlayRequestCoordinatorDelegateImpl + : public OverlayRequestCoordinatorDelegate { public: - OverlayDismissalHelper( + OverlayRequestCoordinatorDelegateImpl( OverlayPresentationContextImpl* presentation_context); - ~OverlayDismissalHelper() override; + ~OverlayRequestCoordinatorDelegateImpl() override; // OverlayUIDismissalDelegate: + void OverlayUIDidFinishPresentation(OverlayRequest* request) override; void OverlayUIDidFinishDismissal(OverlayRequest* request) override; private: @@ -119,8 +122,9 @@ OverlayPresenter* presenter_ = nullptr; // The cleanup helper. BrowserShutdownHelper shutdown_helper_; - // The UI dismissal helper. - OverlayDismissalHelper ui_dismissal_helper_; + // The delegate used to intercept presentation/dismissal events from + // OverlayRequestCoordinators. + OverlayRequestCoordinatorDelegateImpl coordinator_delegate_; // The coordinator factory that provides the UI for the overlays at this // modality. OverlayRequestCoordinatorFactory* coordinator_factory_ = nil;
diff --git a/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.mm b/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.mm index 74767b8..6150255 100644 --- a/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.mm +++ b/ios/chrome/browser/ui/overlays/overlay_presentation_context_impl.mm
@@ -45,7 +45,7 @@ OverlayModality modality) : presenter_(OverlayPresenter::FromBrowser(browser, modality)), shutdown_helper_(browser, presenter_), - ui_dismissal_helper_(this), + coordinator_delegate_(this), coordinator_factory_([OverlayRequestCoordinatorFactory factoryForBrowser:browser modality:modality]), @@ -98,6 +98,7 @@ void OverlayPresentationContextImpl::ShowOverlayUI( OverlayPresenter* presenter, OverlayRequest* request, + OverlayPresentationCallback presentation_callback, OverlayDismissalCallback dismissal_callback) { DCHECK_EQ(presenter_, presenter); // Create the UI state for |request| if necessary. @@ -105,7 +106,7 @@ states_[request] = std::make_unique<OverlayRequestUIState>(request); // Present the overlay UI and update the UI state. GetRequestUIState(request)->OverlayPresentionRequested( - std::move(dismissal_callback)); + std::move(presentation_callback), std::move(dismissal_callback)); SetRequest(request); } @@ -202,7 +203,7 @@ overlay_coordinator.baseViewController != container_view_controller) { overlay_coordinator = [coordinator_factory_ newCoordinatorForRequest:request_ - dismissalDelegate:&ui_dismissal_helper_ + delegate:&coordinator_delegate_ baseViewController:container_view_controller]; state->OverlayUIWillBePresented(overlay_coordinator); } @@ -258,16 +259,20 @@ #pragma mark OverlayDismissalHelper -OverlayPresentationContextImpl::OverlayDismissalHelper::OverlayDismissalHelper( - OverlayPresentationContextImpl* presentation_context) +OverlayPresentationContextImpl::OverlayRequestCoordinatorDelegateImpl:: + OverlayRequestCoordinatorDelegateImpl( + OverlayPresentationContextImpl* presentation_context) : presentation_context_(presentation_context) { DCHECK(presentation_context_); } -OverlayPresentationContextImpl::OverlayDismissalHelper:: - ~OverlayDismissalHelper() = default; +OverlayPresentationContextImpl::OverlayRequestCoordinatorDelegateImpl:: + ~OverlayRequestCoordinatorDelegateImpl() = default; -void OverlayPresentationContextImpl::OverlayDismissalHelper:: +void OverlayPresentationContextImpl::OverlayRequestCoordinatorDelegateImpl:: + OverlayUIDidFinishPresentation(OverlayRequest* request) {} + +void OverlayPresentationContextImpl::OverlayRequestCoordinatorDelegateImpl:: OverlayUIDidFinishDismissal(OverlayRequest* request) { DCHECK(request); DCHECK_EQ(presentation_context_->request_, request);
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_coordinator.h b/ios/chrome/browser/ui/overlays/overlay_request_coordinator.h index 02bd7f34..180e195 100644 --- a/ios/chrome/browser/ui/overlays/overlay_request_coordinator.h +++ b/ios/chrome/browser/ui/overlays/overlay_request_coordinator.h
@@ -7,7 +7,7 @@ #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" -class OverlayUIDismissalDelegate; +class OverlayRequestCoordinatorDelegate; class OverlayRequest; // Coordinator superclass used to present UI for an OverlayRequest. @@ -20,8 +20,8 @@ - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser request:(OverlayRequest*)request - dismissalDelegate: - (OverlayUIDismissalDelegate*)dismissalDelegate + delegate:(OverlayRequestCoordinatorDelegate*) + delegate NS_DESIGNATED_INITIALIZER; - (instancetype)initWithBaseViewController:(UIViewController*)viewController browserState: @@ -30,12 +30,11 @@ - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser NS_UNAVAILABLE; -// The OverlayUIDismissalDelegate passed on initialization. Used to communicate -// when the overlay UI is finished being dismissed, which may occur after -// |-stop| even if the overlay is stopped without animation. This notifies -// OverlayPresenter that the presentation context is clear to show the next -// requested overlay. -@property(nonatomic, readonly) OverlayUIDismissalDelegate* dismissalDelegate; +// The OverlayRequestCoordinatorDelegate passed on initialization. Used to +// communicate when the overlay UI is finished being presented and dismissed. +// Overlay UI presentation and dismissal may occur after |-start| and |-stop|, +// even if the overlay is stopped without animation. +@property(nonatomic, readonly) OverlayRequestCoordinatorDelegate* delegate; // The request used to configure the overlay UI. @property(nonatomic, readonly) OverlayRequest* request;
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm b/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm index 0bde829..fdcd07b 100644 --- a/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/overlay_request_coordinator.mm
@@ -5,7 +5,7 @@ #import "ios/chrome/browser/ui/overlays/overlay_request_coordinator.h" #include "base/logging.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -20,15 +20,15 @@ - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser request:(OverlayRequest*)request - dismissalDelegate: - (OverlayUIDismissalDelegate*)dismissalDelegate { + delegate:(OverlayRequestCoordinatorDelegate*) + delegate { DCHECK([[self class] supportsRequest:request]); self = [super initWithBaseViewController:viewController browser:browser]; if (self) { _request = request; DCHECK(_request); - _dismissalDelegate = dismissalDelegate; - DCHECK(_dismissalDelegate); + _delegate = delegate; + DCHECK(_delegate); } return self; }
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h b/ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h new file mode 100644 index 0000000..266b4f02 --- /dev/null +++ b/ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h
@@ -0,0 +1,26 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_COORDINATOR_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_COORDINATOR_DELEGATE_H_ + +class OverlayRequest; + +// Delegate class used to communicate overlay UI presentation events back to +// OverlayPresenter. +class OverlayRequestCoordinatorDelegate { + public: + OverlayRequestCoordinatorDelegate() = default; + virtual ~OverlayRequestCoordinatorDelegate() = default; + + // Called to notify the delegate that the UI for |request| has finished being + // presented. + virtual void OverlayUIDidFinishPresentation(OverlayRequest* request) = 0; + + // Called to notify the delegate that the UI for |request| is finished + // being dismissed. + virtual void OverlayUIDidFinishDismissal(OverlayRequest* request) = 0; +}; + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_REQUEST_COORDINATOR_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_ui_state.h b/ios/chrome/browser/ui/overlays/overlay_request_ui_state.h index 1e4a2a8..6abe86e4 100644 --- a/ios/chrome/browser/ui/overlays/overlay_request_ui_state.h +++ b/ios/chrome/browser/ui/overlays/overlay_request_ui_state.h
@@ -8,6 +8,7 @@ #import <Foundation/Foundation.h> #include "ios/chrome/browser/overlays/public/overlay_dismissal_callback.h" +#include "ios/chrome/browser/overlays/public/overlay_presentation_callback.h" @class OverlayRequestCoordinator; class OverlayRequest; @@ -21,9 +22,12 @@ // Called when the OverlayPresenter requests the presentation of |request_|. // This may or may not correspond with an OverlayUIWasPresented() if the - // hierarchy is not ready for presentation (i.e. overlay presentation for a - // Browser whose UI is not currently on-screen). - void OverlayPresentionRequested(OverlayDismissalCallback callback); + // presentation context is inactive. |presentation_callback| and + // |dismissal_callback| are stored in the state, and will be executed when + // OverlayUIWasPresented() and OverlayUIWasDismissed() are called. + void OverlayPresentionRequested( + OverlayPresentationCallback presentation_callback, + OverlayDismissalCallback dismissal_callback); // Notifies the state that the UI is about to be presented using // |coordinator|. @@ -48,6 +52,7 @@ OverlayRequest* request_ = nullptr; OverlayRequestCoordinator* coordinator_ = nil; bool has_ui_been_presented_ = false; + OverlayPresentationCallback presentation_callback_; OverlayDismissalReason dismissal_reason_ = OverlayDismissalReason::kUserInteraction; OverlayDismissalCallback dismissal_callback_;
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_ui_state.mm b/ios/chrome/browser/ui/overlays/overlay_request_ui_state.mm index 5073250..6f30a5e 100644 --- a/ios/chrome/browser/ui/overlays/overlay_request_ui_state.mm +++ b/ios/chrome/browser/ui/overlays/overlay_request_ui_state.mm
@@ -23,9 +23,14 @@ } void OverlayRequestUIState::OverlayPresentionRequested( - OverlayDismissalCallback callback) { + OverlayPresentationCallback presentation_callback, + OverlayDismissalCallback dismissal_callback) { + DCHECK(presentation_callback_.is_null()); DCHECK(dismissal_callback_.is_null()); - dismissal_callback_ = std::move(callback); + DCHECK(!presentation_callback.is_null()); + DCHECK(!dismissal_callback.is_null()); + presentation_callback_ = std::move(presentation_callback); + dismissal_callback_ = std::move(dismissal_callback); // The default dismissal reason is kUserInteraction. This is to avoid // additional bookkeeping for overlays dismissed by user interaction. // Overlays explicitly dismissed by OverlayPresenter set the reason to kHide @@ -41,6 +46,7 @@ void OverlayRequestUIState::OverlayUIWasPresented() { has_ui_been_presented_ = true; + std::move(presentation_callback_).Run(); } void OverlayRequestUIState::OverlayUIWasDismissed() {
diff --git a/ios/chrome/browser/ui/overlays/overlay_request_ui_state_unittest.mm b/ios/chrome/browser/ui/overlays/overlay_request_ui_state_unittest.mm index cbc9a1c..dad5aa0 100644 --- a/ios/chrome/browser/ui/overlays/overlay_request_ui_state_unittest.mm +++ b/ios/chrome/browser/ui/overlays/overlay_request_ui_state_unittest.mm
@@ -10,7 +10,7 @@ #include "ios/chrome/browser/overlays/public/overlay_request.h" #include "ios/chrome/browser/overlays/test/fake_overlay_user_data.h" #import "ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator.h" -#include "ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.h" +#include "ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.h" #include "testing/platform_test.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -38,8 +38,10 @@ // resets the default dismissal reason to kUserInteraction. TEST_F(OverlayRequestUIStateTest, OverlayPresentionRequested) { ASSERT_FALSE(state().has_callback()); - state().OverlayPresentionRequested(base::BindOnce(^(OverlayDismissalReason){ - })); + state().OverlayPresentionRequested(base::BindOnce(^{ + }), + base::BindOnce(^(OverlayDismissalReason){ + })); EXPECT_TRUE(state().has_callback()); EXPECT_EQ(OverlayDismissalReason::kUserInteraction, state().dismissal_reason()); @@ -47,13 +49,13 @@ // Tests that OverlayUIWillBePresented() stores the coordinator in the state. TEST_F(OverlayRequestUIStateTest, OverlayUIWillBePresented) { - FakeDismissalDelegate dismissal_delegate; + FakeOverlayRequestCoordinatorDelegate delegate; FakeOverlayRequestCoordinator* coordinator = [[FakeOverlayRequestCoordinator alloc] initWithBaseViewController:nil browser:nullptr request:request() - dismissalDelegate:&dismissal_delegate]; + delegate:&delegate]; state().OverlayUIWillBePresented(coordinator); EXPECT_EQ(coordinator, state().coordinator()); } @@ -61,23 +63,32 @@ // Tests that OverlayUIWasPresented() correctly updates has_ui_been_presented(). TEST_F(OverlayRequestUIStateTest, OverlayUIWasPresented) { ASSERT_FALSE(state().has_ui_been_presented()); + __block bool presentation_callback_executed = false; + state().OverlayPresentionRequested(base::BindOnce(^{ + presentation_callback_executed = true; + }), + base::BindOnce(^(OverlayDismissalReason){ + })); state().OverlayUIWasPresented(); EXPECT_TRUE(state().has_ui_been_presented()); + EXPECT_TRUE(presentation_callback_executed); } // Tests that OverlayUIWasDismissed() executes the dismissal callback. TEST_F(OverlayRequestUIStateTest, OverlayUIWasDismissed) { __block bool dismissal_callback_executed = false; - state().OverlayPresentionRequested(base::BindOnce(^(OverlayDismissalReason) { - dismissal_callback_executed = true; - })); - FakeDismissalDelegate dismissal_delegate; + state().OverlayPresentionRequested(base::BindOnce(^{ + }), + base::BindOnce(^(OverlayDismissalReason) { + dismissal_callback_executed = true; + })); + FakeOverlayRequestCoordinatorDelegate delegate; FakeOverlayRequestCoordinator* coordinator = [[FakeOverlayRequestCoordinator alloc] initWithBaseViewController:nil browser:nullptr request:request() - dismissalDelegate:&dismissal_delegate]; + delegate:&delegate]; state().OverlayUIWillBePresented(coordinator); state().OverlayUIWasPresented(); state().OverlayUIWasDismissed();
diff --git a/ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h b/ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h deleted file mode 100644 index ad84fa3..0000000 --- a/ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_UI_DISMISSAL_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_UI_DISMISSAL_DELEGATE_H_ - -class OverlayRequest; - -// Delegate class used to communicate dismissal events back to OverlayPresenter. -class OverlayUIDismissalDelegate { - public: - OverlayUIDismissalDelegate() = default; - virtual ~OverlayUIDismissalDelegate() = default; - - // Called to notify the delegate that the UI for |request|'s UI is finished - // being dismissed. - virtual void OverlayUIDidFinishDismissal(OverlayRequest* request) = 0; -}; - -#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_OVERLAY_UI_DISMISSAL_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/overlays/test/BUILD.gn b/ios/chrome/browser/ui/overlays/test/BUILD.gn index d5c019f5..a01a5d8 100644 --- a/ios/chrome/browser/ui/overlays/test/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/test/BUILD.gn
@@ -7,8 +7,8 @@ sources = [ "fake_overlay_request_coordinator.h", "fake_overlay_request_coordinator.mm", - "fake_overlay_ui_dismissal_delegate.cc", - "fake_overlay_ui_dismissal_delegate.h", + "fake_overlay_request_coordinator_delegate.cc", + "fake_overlay_request_coordinator_delegate.h", ] configs += [ "//build/config/compiler:enable_arc" ]
diff --git a/ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.cc b/ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.cc new file mode 100644 index 0000000..95d07bb --- /dev/null +++ b/ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.cc
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.h" + +FakeOverlayRequestCoordinatorDelegate::FakeOverlayRequestCoordinatorDelegate() = + default; +FakeOverlayRequestCoordinatorDelegate:: + ~FakeOverlayRequestCoordinatorDelegate() = default; + +bool FakeOverlayRequestCoordinatorDelegate::HasUIBeenPresented( + OverlayRequest* request) const { + return states_.find(request) != states_.end() && + states_.at(request) == PresentationState::kPresented; +} + +bool FakeOverlayRequestCoordinatorDelegate::HasUIBeenDismissed( + OverlayRequest* request) const { + return states_.find(request) != states_.end() && + states_.at(request) == PresentationState::kDismissed; +} + +void FakeOverlayRequestCoordinatorDelegate::OverlayUIDidFinishPresentation( + OverlayRequest* request) { + states_[request] = PresentationState::kPresented; +} + +void FakeOverlayRequestCoordinatorDelegate::OverlayUIDidFinishDismissal( + OverlayRequest* request) { + states_[request] = PresentationState::kDismissed; +}
diff --git a/ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.h b/ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.h new file mode 100644 index 0000000..920556f --- /dev/null +++ b/ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_TEST_FAKE_OVERLAY_REQUEST_COORDINATOR_DELEGATE_H_ +#define IOS_CHROME_BROWSER_UI_OVERLAYS_TEST_FAKE_OVERLAY_REQUEST_COORDINATOR_DELEGATE_H_ + +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" + +#include <map> + +// Fake implementation of OverlayRequestCoordinatorDelegate. +class FakeOverlayRequestCoordinatorDelegate + : public OverlayRequestCoordinatorDelegate { + public: + FakeOverlayRequestCoordinatorDelegate(); + ~FakeOverlayRequestCoordinatorDelegate() override; + + // Whether the overlay UI for |request| has been presented. + bool HasUIBeenPresented(OverlayRequest* request) const; + + // Whether the overlay UI for |request| has been dismissed. + bool HasUIBeenDismissed(OverlayRequest* request) const; + + // OverlayRequestCoordinatorDelegate: + void OverlayUIDidFinishPresentation(OverlayRequest* request) override; + void OverlayUIDidFinishDismissal(OverlayRequest* request) override; + + private: + enum class PresentationState { kNotPresented, kPresented, kDismissed }; + std::map<OverlayRequest*, PresentationState> states_; +}; + +#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_TEST_FAKE_OVERLAY_REQUEST_COORDINATOR_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.cc b/ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.cc deleted file mode 100644 index 88ee77f..0000000 --- a/ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.h" - -FakeDismissalDelegate::FakeDismissalDelegate() = default; -FakeDismissalDelegate::~FakeDismissalDelegate() = default; - -bool FakeDismissalDelegate::HasUIBeenDismissed(OverlayRequest* request) const { - return dismissed_requests_.find(request) != dismissed_requests_.end(); -} - -void FakeDismissalDelegate::OverlayUIDidFinishDismissal( - OverlayRequest* request) { - dismissed_requests_.insert(request); -}
diff --git a/ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.h b/ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.h deleted file mode 100644 index 0334c4c9..0000000 --- a/ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.h +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_TEST_FAKE_OVERLAY_UI_DISMISSAL_DELEGATE_H_ -#define IOS_CHROME_BROWSER_UI_OVERLAYS_TEST_FAKE_OVERLAY_UI_DISMISSAL_DELEGATE_H_ - -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" - -#include <set> - -// Fake implementation of OverlayUIDismissalDelegate. -class FakeDismissalDelegate : public OverlayUIDismissalDelegate { - public: - FakeDismissalDelegate(); - ~FakeDismissalDelegate() override; - - // Whether the overlay UI for |request| has been dismissed. - bool HasUIBeenDismissed(OverlayRequest* request) const; - - // OverlayUIDismissalDelegate: - void OverlayUIDidFinishDismissal(OverlayRequest* request) override; - - private: - std::set<OverlayRequest*> dismissed_requests_; -}; - -#endif // IOS_CHROME_BROWSER_UI_OVERLAYS_TEST_FAKE_OVERLAY_UI_DISMISSAL_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm index 10f1587..b996e58 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_coordinator.mm
@@ -7,7 +7,7 @@ #include "ios/chrome/browser/overlays/public/overlay_request.h" #include "ios/chrome/browser/overlays/public/web_content_area/app_launcher_alert_overlay.h" #import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/ui/overlays/web_content_area/app_launcher/app_launcher_alert_overlay_mediator.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -80,8 +80,8 @@ if (!strongSelf) return; strongSelf.alertViewController = nil; - strongSelf.dismissalDelegate - ->OverlayUIDidFinishDismissal(weakSelf.request); + strongSelf.delegate->OverlayUIDidFinishDismissal( + weakSelf.request); }]; self.started = NO; }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm index 35767fb..a3b63ac 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_coordinator.mm
@@ -7,7 +7,7 @@ #include "ios/chrome/browser/overlays/public/overlay_request.h" #include "ios/chrome/browser/overlays/public/web_content_area/http_auth_overlay.h" #import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/ui/overlays/web_content_area/http_auth_dialogs/http_auth_dialog_overlay_mediator.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -97,8 +97,8 @@ if (!strongSelf) return; strongSelf.alertViewController = nil; - strongSelf.dismissalDelegate - ->OverlayUIDidFinishDismissal(weakSelf.request); + strongSelf.delegate->OverlayUIDidFinishDismissal( + weakSelf.request); }]; self.started = NO; }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator_unittest.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator_unittest.mm index 611745b..c618bde 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_alert_overlay_coordinator_unittest.mm
@@ -47,5 +47,5 @@ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^bool { return !alert.presentingViewController; })); - EXPECT_TRUE(dismissal_delegate().HasUIBeenDismissed(request)); + EXPECT_TRUE(delegate().HasUIBeenDismissed(request)); }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm index 59be3598..2e2e768 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator.mm
@@ -15,7 +15,7 @@ #import "ios/chrome/browser/overlays/public/web_content_area/java_script_confirmation_overlay.h" #import "ios/chrome/browser/ui/alert_view_controller/alert_action.h" #import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator+subclassing.h" #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator_unittest.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator_unittest.mm index 1a317fb..6728f22 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_confirmation_overlay_coordinator_unittest.mm
@@ -48,5 +48,5 @@ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^bool { return !confirmation.presentingViewController; })); - EXPECT_TRUE(dismissal_delegate().HasUIBeenDismissed(request)); + EXPECT_TRUE(delegate().HasUIBeenDismissed(request)); }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator.mm index 053bc2be..568e874 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator.mm
@@ -10,7 +10,7 @@ #include "ios/chrome/browser/overlays/public/web_content_area/java_script_dialog_source.h" #import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h" #import "ios/chrome/browser/ui/dialogs/java_script_dialog_blocking_state.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator+subclassing.h" #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_mediator.h" #include "ios/chrome/grit/ios_strings.h" @@ -70,9 +70,14 @@ UIModalTransitionStyleCrossDissolve; self.mediator = [self newMediator]; self.mediator.consumer = self.alertViewController; - [self.baseViewController presentViewController:self.alertViewController - animated:animated - completion:nil]; + __weak __typeof__(self) weakSelf = self; + [self.baseViewController + presentViewController:self.alertViewController + animated:animated + completion:^{ + weakSelf.delegate->OverlayUIDidFinishPresentation( + weakSelf.request); + }]; self.started = YES; } @@ -87,8 +92,8 @@ if (!strongSelf) return; strongSelf.alertViewController = nil; - strongSelf.dismissalDelegate - ->OverlayUIDidFinishDismissal(weakSelf.request); + strongSelf.delegate->OverlayUIDidFinishDismissal( + weakSelf.request); }]; self.started = NO; }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator_unittest.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator_unittest.mm index c84ed3d..eda2d53 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_coordinator_unittest.mm
@@ -46,5 +46,5 @@ EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForUIElementTimeout, ^bool { return !prompt.presentingViewController; })); - EXPECT_TRUE(dismissal_delegate().HasUIBeenDismissed(request)); + EXPECT_TRUE(delegate().HasUIBeenDismissed(request)); }
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm index 2cfa332..b11f9f2 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_prompt_overlay_mediator.mm
@@ -12,7 +12,7 @@ #import "ios/chrome/browser/ui/alert_view_controller/alert_action.h" #import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h" #import "ios/chrome/browser/ui/elements/text_field_configuration.h" -#import "ios/chrome/browser/ui/overlays/overlay_ui_dismissal_delegate.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_blocking_action.h" #import "ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/java_script_dialog_overlay_coordinator+subclassing.h" #include "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.h b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.h index 52acfac4..3368dba 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.h +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.h
@@ -11,7 +11,7 @@ #import "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/overlays/public/overlay_request.h" -#include "ios/chrome/browser/ui/overlays/test/fake_overlay_ui_dismissal_delegate.h" +#include "ios/chrome/browser/ui/overlays/test/fake_overlay_request_coordinator_delegate.h" #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/test/scoped_key_window.h" @@ -29,8 +29,8 @@ ~JavaScriptDialogOverlayCoordinatorTest() override; // Accessors: - const FakeDismissalDelegate& dismissal_delegate() const { - return dismissal_delegate_; + const FakeOverlayRequestCoordinatorDelegate& delegate() const { + return delegate_; } // Sets the request for the test. Setting to a new value will create a @@ -58,7 +58,7 @@ std::unique_ptr<Browser> browser_; UIViewController* base_view_controller; std::unique_ptr<OverlayRequest> request_; - FakeDismissalDelegate dismissal_delegate_; + FakeOverlayRequestCoordinatorDelegate delegate_; OverlayRequestCoordinator* coordinator_; };
diff --git a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.mm b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.mm index 9e5254e..5deb3e3 100644 --- a/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.mm +++ b/ios/chrome/browser/ui/overlays/web_content_area/java_script_dialogs/test/java_script_dialog_overlay_coordinator_test.mm
@@ -47,7 +47,7 @@ initWithBrowser:browser_.get() supportedOverlayRequestCoordinatorClasses:coordinator_classes]; coordinator_ = [factory newCoordinatorForRequest:request_.get() - dismissalDelegate:&dismissal_delegate_ + delegate:&delegate_ baseViewController:base_view_controller]; }
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm index a1defd6..aaba345 100644 --- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm +++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm
@@ -270,15 +270,13 @@ _addTabActionImageView = [[UIImageView alloc] init]; _addTabActionImageView.image = [[UIImage imageNamed:kNewTabActionImage] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - _addTabActionImageView.tintColor = - [UIColor colorNamed:@"tab_toolbar_button_color"]; + _addTabActionImageView.tintColor = [UIColor colorNamed:kToolbarButtonColor]; [_addTabActionImageView sizeToFit]; [self addSubview:_addTabActionImageView]; _reloadActionImageView = [[UIImageView alloc] init]; _reloadActionImageView.image = [[UIImage imageNamed:kReloadActionImage] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - _reloadActionImageView.tintColor = - [UIColor colorNamed:@"tab_toolbar_button_color"]; + _reloadActionImageView.tintColor = [UIColor colorNamed:kToolbarButtonColor]; [_reloadActionImageView sizeToFit]; if (UseRTLLayout()) [_reloadActionImageView setTransform:CGAffineTransformMakeScale(-1, 1)]; @@ -287,7 +285,7 @@ _closeTabActionImageView.image = [[UIImage imageNamed:kCloseActionImage] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; _closeTabActionImageView.tintColor = - [UIColor colorNamed:@"tab_toolbar_button_color"]; + [UIColor colorNamed:kToolbarButtonColor]; [_closeTabActionImageView sizeToFit]; [self addSubview:_closeTabActionImageView]; @@ -320,7 +318,7 @@ _addTabLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _addTabLabel.adjustsFontForContentSizeCategory = NO; - _addTabLabel.textColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; + _addTabLabel.textColor = [UIColor colorNamed:kToolbarButtonColor]; _addTabLabel.text = l10n_util::GetNSString(IDS_IOS_OVERSCROLL_NEW_TAB_LABEL); [self addSubview:_addTabLabel]; @@ -332,7 +330,7 @@ _reloadLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _reloadLabel.adjustsFontForContentSizeCategory = NO; - _reloadLabel.textColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; + _reloadLabel.textColor = [UIColor colorNamed:kToolbarButtonColor]; _reloadLabel.text = l10n_util::GetNSString(IDS_IOS_OVERSCROLL_RELOAD_LABEL); [self addSubview:_reloadLabel]; _closeTabLabel = [[UILabel alloc] init]; @@ -343,7 +341,7 @@ _closeTabLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _closeTabLabel.adjustsFontForContentSizeCategory = NO; - _closeTabLabel.textColor = [UIColor colorNamed:@"tab_toolbar_button_color"]; + _closeTabLabel.textColor = [UIColor colorNamed:kToolbarButtonColor]; _closeTabLabel.text = l10n_util::GetNSString(IDS_IOS_OVERSCROLL_CLOSE_TAB_LABEL); [self addSubview:_closeTabLabel]; @@ -977,8 +975,7 @@ // Fallback for iOS 12. if (self.incognito) { - UIColor* buttonColor = - [UIColor colorNamed:@"tab_toolbar_button_color_incognito"]; + UIColor* buttonColor = [UIColor colorNamed:kToolbarButtonDarkColor]; _addTabActionImageView.tintColor = buttonColor; _reloadActionImageView.tintColor = buttonColor; _closeTabActionImageView.tintColor = buttonColor;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm index 582e51b..6d4aaef5 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_item.mm
@@ -90,15 +90,7 @@ URLCell.metadataLabel.text = self.distillationSizeText; URLCell.cellUniqueIdentifier = base::SysUTF8ToNSString(self.entryURL.host()); URLCell.accessibilityTraits |= UIAccessibilityTraitButton; - // If the background color specified by the styler is opaque, use it as the - // subview backround colors as well. - UIColor* backgroundColor = styler.tableViewBackgroundColor; - if (AreCGFloatsEqual(CGColorGetAlpha(backgroundColor.CGColor), 1.0)) { - URLCell.faviconContainerView.backgroundColor = backgroundColor; - URLCell.titleLabel.backgroundColor = backgroundColor; - URLCell.URLLabel.backgroundColor = backgroundColor; - URLCell.metadataLabel.backgroundColor = backgroundColor; - } + if (styler.cellTitleColor) URLCell.titleLabel.textColor = styler.cellTitleColor; [URLCell.faviconView configureWithAttributes:self.attributes];
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm index 8b9a052..a1e754cc 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm
@@ -65,15 +65,6 @@ cell.metadataLabel.text = self.metadata; cell.cellUniqueIdentifier = self.uniqueIdentifier; cell.accessibilityTraits |= UIAccessibilityTraitButton; - // If the background color specified by the styler is opaque, use it as the - // subview backround colors as well. - UIColor* backgroundColor = styler.tableViewBackgroundColor; - if (AreCGFloatsEqual(CGColorGetAlpha(backgroundColor.CGColor), 1.0)) { - cell.faviconContainerView.backgroundColor = styler.tableViewBackgroundColor; - cell.titleLabel.backgroundColor = styler.tableViewBackgroundColor; - cell.URLLabel.backgroundColor = styler.tableViewBackgroundColor; - cell.metadataLabel.backgroundColor = styler.tableViewBackgroundColor; - } if (styler.cellTitleColor) cell.titleLabel.textColor = styler.cellTitleColor;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm b/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm index 0af59da..46c00fd 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm
@@ -78,21 +78,6 @@ EXPECT_FALSE(URLCell.metadataLabel.hidden); } -TEST_F(TableViewURLItemTest, ConfigureCellWithStyler) { - TableViewURLItem* item = [[TableViewURLItem alloc] initWithType:0]; - TableViewURLCell* cell = [[[item cellClass] alloc] init]; - ASSERT_TRUE([cell isMemberOfClass:[TableViewURLCell class]]); - - ChromeTableViewStyler* styler = [[ChromeTableViewStyler alloc] init]; - UIColor* testColor = UIColor.redColor; - styler.tableViewBackgroundColor = testColor; - [item configureCell:cell withStyler:styler]; - EXPECT_NSEQ(testColor, cell.faviconContainerView.backgroundColor); - EXPECT_NSEQ(testColor, cell.titleLabel.backgroundColor); - EXPECT_NSEQ(testColor, cell.URLLabel.backgroundColor); - EXPECT_NSEQ(testColor, cell.metadataLabel.backgroundColor); -} - // Tests that the suppelemental URL text is appended to the hostname when there // is a title. TEST_F(TableViewURLItemTest, SupplementalURLTextWithTitle) {
diff --git a/ios/chrome/browser/ui/table_view/chrome_table_view_styler.h b/ios/chrome/browser/ui/table_view/chrome_table_view_styler.h index 376d5c21..c0f7980 100644 --- a/ios/chrome/browser/ui/table_view/chrome_table_view_styler.h +++ b/ios/chrome/browser/ui/table_view/chrome_table_view_styler.h
@@ -9,9 +9,7 @@ @interface ChromeTableViewStyler : NSObject -// The background color for the table view and its cells. If this is set to an -// opaque color, cells can choose to make themselves opaque and draw their own -// background as a performance optimization. +// The background color for the table view. @property(nonatomic, readwrite, strong) UIColor* tableViewBackgroundColor; // The background color for the cell. It overrides |tableViewBackgroundColor| // for the cell background if it is not nil.
diff --git a/ios/chrome/browser/ui/tabs/BUILD.gn b/ios/chrome/browser/ui/tabs/BUILD.gn index 454bcbf67..8f7a5de 100644 --- a/ios/chrome/browser/ui/tabs/BUILD.gn +++ b/ios/chrome/browser/ui/tabs/BUILD.gn
@@ -121,7 +121,6 @@ ":tabs", "//ios/chrome/app/strings", "//ios/chrome/browser", - "//ios/chrome/browser/ui/util", "//ios/chrome/test/app:test_support", "//ios/chrome/test/earl_grey:test_support", "//ios/third_party/earl_grey:earl_grey+link",
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm b/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm index 5d4865f2..ecbe1d92 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_egtest.mm
@@ -8,7 +8,6 @@ #include "ios/chrome/browser/system_flags.h" #import "ios/chrome/browser/tabs/tab_title_util.h" #import "ios/chrome/browser/ui/tabs/tab_view.h" -#import "ios/chrome/browser/ui/util/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/app/tab_test_util.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" @@ -36,7 +35,7 @@ // Test switching tabs using the tab strip. - (void)testTabStripSwitchTabs { // Only iPad has a tab strip. - if (IsCompactWidth()) { + if ([ChromeEarlGrey isCompactWidth]) { return; }
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index 1b44b811..6d8d2a9 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -82,7 +82,6 @@ "toolbar_progress_bar.mm", ] deps = [ - "resources:tab_toolbar_shadow_color", "//base", "//ios/chrome/app/strings", "//ios/chrome/browser/ui/activity_services/requirements", @@ -98,6 +97,7 @@ "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util", "//ios/chrome/common:timing", + "//ios/chrome/common/colors", "//ios/chrome/common/ui_util", "//ios/third_party/material_components_ios", "//ui/base",
diff --git a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm index be36564..0bb265dc 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive_toolbar_egtest.mm
@@ -444,7 +444,7 @@ // Tests that tapping a button cancels the focus on the omnibox. - (void)testCancelOmniboxEdit { - if (IsCompactWidth()) { + if ([ChromeEarlGrey isCompactWidth]) { EARL_GREY_TEST_SKIPPED(@"No button to tap in compact width."); }
diff --git a/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn b/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn index 971dc2a..fda04ab 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/buttons/BUILD.gn
@@ -25,10 +25,8 @@ "toolbar_type.h", ] deps = [ - "resources:tab_toolbar_button_color", "resources:tab_toolbar_button_color_highlighted", "resources:tab_toolbar_button_color_highlighted_incognito", - "resources:tab_toolbar_button_color_incognito", "resources:tab_toolbar_button_halo_color", "resources:tab_toolbar_button_halo_color_incognito", "resources:toolbar_back",
diff --git a/ios/chrome/browser/ui/toolbar/buttons/resources/BUILD.gn b/ios/chrome/browser/ui/toolbar/buttons/resources/BUILD.gn index 0f5b2ee9..0d5e7e4 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/resources/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/buttons/resources/BUILD.gn
@@ -4,18 +4,6 @@ import("//build/config/ios/asset_catalog.gni") -colorset("tab_toolbar_button_color") { - sources = [ - "tab_toolbar_button_color.colorset/Contents.json", - ] -} - -colorset("tab_toolbar_button_color_incognito") { - sources = [ - "tab_toolbar_button_color_incognito.colorset/Contents.json", - ] -} - colorset("tab_toolbar_button_color_highlighted") { sources = [ "tab_toolbar_button_color_highlighted.colorset/Contents.json",
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.mm index c3d9f8b..baff1ed 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.mm
@@ -42,8 +42,8 @@ - (UIColor*)buttonsTintColor { return color::IncognitoDynamicColor( - self.style == INCOGNITO, [UIColor colorNamed:@"tab_toolbar_button_color"], - [UIColor colorNamed:@"tab_toolbar_button_color_incognito"]); + self.style == INCOGNITO, [UIColor colorNamed:kToolbarButtonColor], + [UIColor colorNamed:kToolbarButtonDarkColor]); } - (UIColor*)buttonsTintColorHighlighted {
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm index 290f0e41..6e7cdb8b 100644 --- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view.mm
@@ -17,6 +17,7 @@ #import "ios/chrome/browser/ui/toolbar/toolbar_progress_bar.h" #import "ios/chrome/browser/ui/util/dynamic_type_util.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ui/gfx/ios/uikit_util.h" @@ -278,8 +279,7 @@ // Sets the separator up. - (void)setUpSeparator { self.separator = [[UIView alloc] init]; - self.separator.backgroundColor = - [UIColor colorNamed:@"tab_toolbar_shadow_color"]; + self.separator.backgroundColor = [UIColor colorNamed:kToolbarShadowColor]; self.separator.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:self.separator]; }
diff --git a/ios/chrome/browser/ui/toolbar/resources/BUILD.gn b/ios/chrome/browser/ui/toolbar/resources/BUILD.gn deleted file mode 100644 index f614247f..0000000 --- a/ios/chrome/browser/ui/toolbar/resources/BUILD.gn +++ /dev/null
@@ -1,11 +0,0 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/ios/asset_catalog.gni") - -colorset("tab_toolbar_shadow_color") { - sources = [ - "tab_toolbar_shadow_color.colorset/Contents.json", - ] -}
diff --git a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm index 329a972..bcbb312 100644 --- a/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/secondary_toolbar_view.mm
@@ -13,6 +13,7 @@ #import "ios/chrome/browser/ui/toolbar/public/features.h" #import "ios/chrome/browser/ui/toolbar_container/toolbar_collapsing.h" #import "ios/chrome/browser/ui/util/named_guide.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ui/gfx/ios/uikit_util.h" @@ -125,8 +126,7 @@ ]; self.separator = [[UIView alloc] init]; - self.separator.backgroundColor = - [UIColor colorNamed:@"tab_toolbar_shadow_color"]; + self.separator.backgroundColor = [UIColor colorNamed:kToolbarShadowColor]; self.separator.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:self.separator];
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm index 9d34780..830a5a8a 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_egtest.mm
@@ -9,7 +9,6 @@ #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" -#include "ios/chrome/browser/ui/util/ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
diff --git a/ios/chrome/browser/ui/translate/BUILD.gn b/ios/chrome/browser/ui/translate/BUILD.gn index 0bb7481a..16de7a7 100644 --- a/ios/chrome/browser/ui/translate/BUILD.gn +++ b/ios/chrome/browser/ui/translate/BUILD.gn
@@ -57,11 +57,13 @@ "//ios/chrome/browser/ui/fullscreen:ui", "//ios/chrome/browser/ui/infobars:infobars_ui", "//ios/chrome/browser/ui/toolbar/buttons", + "//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/translate/resources:translate_dismiss", "//ios/chrome/browser/ui/translate/resources:translate_icon", "//ios/chrome/browser/ui/translate/resources:translate_options", "//ios/chrome/browser/ui/util", "//ios/chrome/common:common_extension", + "//ios/chrome/common/colors:colors", "//ios/chrome/common/ui_util", "//ios/third_party/material_components_ios", "//ui/base",
diff --git a/ios/chrome/browser/ui/translate/resources/BUILD.gn b/ios/chrome/browser/ui/translate/resources/BUILD.gn index 2666207..bb950ea 100644 --- a/ios/chrome/browser/ui/translate/resources/BUILD.gn +++ b/ios/chrome/browser/ui/translate/resources/BUILD.gn
@@ -7,7 +7,6 @@ imageset("translate_icon") { sources = [ "translate_icon.imageset/Contents.json", - "translate_icon.imageset/translate_icon.png", "translate_icon.imageset/translate_icon@2x.png", "translate_icon.imageset/translate_icon@3x.png", ]
diff --git a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/Contents.json b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/Contents.json index 8637523..66ca5d8 100644 --- a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/Contents.json +++ b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/Contents.json
@@ -1,23 +1,18 @@ { - "images": [ - { - "idiom": "universal", - "scale": "1x", - "filename": "translate_icon.png" - }, - { - "idiom": "universal", - "scale": "2x", - "filename": "translate_icon@2x.png" - }, - { - "idiom": "universal", - "scale": "3x", - "filename": "translate_icon@3x.png" - } - ], - "info": { - "version": 1, - "author": "xcode" + "images" : [ + { + "idiom" : "universal", + "filename" : "translate_icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "translate_icon@3x.png", + "scale" : "3x" } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } }
diff --git a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon.png b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon.png deleted file mode 100644 index 11d7a57..0000000 --- a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@2x.png b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@2x.png index 42ad442..b7bd9842 100644 --- a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@2x.png +++ b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@3x.png b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@3x.png index 76bba6c..09b11e2 100644 --- a/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@3x.png +++ b/ios/chrome/browser/ui/translate/resources/translate_icon.imageset/translate_icon@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.mm index a4d20ec..db246f9 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.mm
@@ -131,11 +131,10 @@ [self addSubview:self.languagesScrollView]; self.gradientLayer = [CAGradientLayer layer]; - self.gradientLayer.colors = - [NSArray arrayWithObjects:(id)[[UIColor clearColor] CGColor], - (id)[[UIColor whiteColor] CGColor], - (id)[[UIColor whiteColor] CGColor], - (id)[[UIColor clearColor] CGColor], nil]; + self.gradientLayer.colors = @[ + (id)UIColor.clearColor.CGColor, (id)UIColor.whiteColor.CGColor, + (id)UIColor.whiteColor.CGColor, (id)UIColor.clearColor.CGColor + ]; // The following two lines make the gradient horizontal. self.gradientLayer.startPoint = CGPointMake(0.0, 0.5); self.gradientLayer.endPoint = CGPointMake(1.0, 0.5);
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm index 3c0c09c9..b277769 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_language_tab_view.mm
@@ -9,6 +9,7 @@ #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.h" #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_view_delegate.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #import "ios/chrome/common/highlight_button.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #import "ios/third_party/material_components_ios/src/components/ActivityIndicator/src/MaterialActivityIndicator.h" @@ -81,8 +82,7 @@ MDCActivityIndicator* activityIndicator = [[MDCActivityIndicator alloc] init]; self.activityIndicator = activityIndicator; self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; - self.activityIndicator.cycleColors = - @[ [[MDCPalette cr_bluePalette] tint500] ]; + self.activityIndicator.cycleColors = @[ [UIColor colorNamed:kBlueColor] ]; [self.activityIndicator setRadius:kActivityIndicatorRadius]; [self addSubview:self.activityIndicator]; @@ -132,8 +132,8 @@ // Returns the button's title color depending on the state. - (UIColor*)titleColor { return self.state == TranslateInfobarLanguageTabViewStateSelected - ? [[MDCPalette cr_bluePalette] tint500] - : [[MDCPalette greyPalette] tint600]; + ? [UIColor colorNamed:kBlueColor] + : [UIColor colorNamed:kTextSecondaryColor]; } // Returns the button's accessibility traits depending on the state.
diff --git a/ios/chrome/browser/ui/translate/translate_infobar_view.mm b/ios/chrome/browser/ui/translate/translate_infobar_view.mm index a4e4740..24c04766 100644 --- a/ios/chrome/browser/ui/translate/translate_infobar_view.mm +++ b/ios/chrome/browser/ui/translate/translate_infobar_view.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/ui/infobars/infobar_constants.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" +#import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view.h" #import "ios/chrome/browser/ui/translate/translate_infobar_language_tab_strip_view_delegate.h" #import "ios/chrome/browser/ui/translate/translate_infobar_view_delegate.h" @@ -19,9 +20,11 @@ #import "ios/chrome/browser/ui/util/layout_guide_names.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/uikit_ui_util.h" +#import "ios/chrome/common/colors/semantic_color_names.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #include "ui/base/l10n/l10n_util.h" +#import "ui/gfx/ios/uikit_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -213,9 +216,22 @@ a11yAnnoucement); } - self.backgroundColor = UIColorFromRGB(kInfobarBackgroundColor); + self.backgroundColor = [UIColor colorNamed:kBackgroundColor]; id<LayoutGuideProvider> safeAreaLayoutGuide = self.safeAreaLayoutGuide; + UIView* separator = [[UIView alloc] init]; + separator.translatesAutoresizingMaskIntoConstraints = NO; + separator.backgroundColor = [UIColor colorNamed:kToolbarShadowColor]; + + [self addSubview:separator]; + CGFloat toolbarHeight = ui::AlignValueToUpperPixel(kToolbarSeparatorHeight); + [NSLayoutConstraint activateConstraints:@[ + [separator.heightAnchor constraintEqualToConstant:toolbarHeight], + [self.topAnchor constraintEqualToAnchor:separator.bottomAnchor], + [self.leadingAnchor constraintEqualToAnchor:separator.leadingAnchor], + [self.trailingAnchor constraintEqualToAnchor:separator.trailingAnchor], + ]]; + // The Content view. Holds all the other subviews. UIView* contentView = [[UIView alloc] init]; contentView.translatesAutoresizingMaskIntoConstraints = NO; @@ -232,11 +248,11 @@ ]]; UIImage* icon = [[UIImage imageNamed:@"translate_icon"] - resizableImageWithCapInsets:UIEdgeInsetsZero - resizingMode:UIImageResizingModeStretch]; + imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; UIImageView* iconView = [[UIImageView alloc] initWithImage:icon]; self.iconView = iconView; self.iconView.translatesAutoresizingMaskIntoConstraints = NO; + self.iconView.tintColor = [UIColor colorNamed:kBlueColor]; [contentView addSubview:self.iconView]; TranslateInfobarLanguageTabStripView* languagesView =
diff --git a/ios/chrome/browser/web/visible_url_egtest.mm b/ios/chrome/browser/web/visible_url_egtest.mm index 4c8dffc..19c076c 100644 --- a/ios/chrome/browser/web/visible_url_egtest.mm +++ b/ios/chrome/browser/web/visible_url_egtest.mm
@@ -18,6 +18,7 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/chrome/test/scoped_eg_synchronization_disabler.h" #import "ios/web/public/navigation/navigation_manager.h" #include "ios/web/public/test/http_server/html_response_provider.h" #import "ios/web/public/test/http_server/http_server.h" @@ -104,8 +105,7 @@ // Spec of the last request URL that reached the server. @property(nonatomic, copy, readonly) NSString* lastRequestURLSpec; -// Pauses response server and disables EG synchronization if |paused| is YES. -// Pending navigation will not complete until server is unpaused. +// Pauses response server. - (void)setServerPaused:(BOOL)paused; // Waits until |_responseProvider| receives a request with the given |URL|. @@ -151,15 +151,6 @@ [ChromeEarlGrey loadURL:_testURL2]; } -- (void)tearDown { - // This test case disables synchronization, so make sure that it is enabled - // if that test has failed and did not enable it back. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - [super tearDown]; -} - #pragma mark - #pragma mark Tests @@ -174,19 +165,24 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the back button in the toolbar and verify that URL2 (committed URL) is - // displayed even though URL1 is a pending URL. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the back button in the toolbar and verify that URL2 (committed URL) + // is displayed even though URL1 is a pending URL. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -195,19 +191,24 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the forward button in the toolbar and verify that URL1 (committed URL) - // is displayed even though URL2 is a pending URL. - [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] - performAction:grey_tap()]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL2], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the forward button in the toolbar and verify that URL1 (committed + // URL) is displayed even though URL2 is a pending URL. + [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] + performAction:grey_tap()]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL2], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL2 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL2 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] assertWithMatcher:grey_notNil()]; @@ -224,13 +225,14 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; - // Re-enable synchronization here to synchronize EarlGrey LongPress and Tap - // actions. - [[GREYConfiguration sharedInstance] - setValue:@(YES) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + { + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; + } + // Go back in history and verify that URL2 (committed URL) is displayed even // though URL1 is a pending URL. [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] @@ -240,17 +242,18 @@ [[EarlGrey selectElementWithMatcher:grey_text(URL1Title)] performAction:grey_tap()]; - [[GREYConfiguration sharedInstance] - setValue:@(NO) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; + { + // Disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; - - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -267,27 +270,30 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + std::unique_ptr<ScopedSynchronizationDisabler> disabler = + std::make_unique<ScopedSynchronizationDisabler>(); + [self setServerPaused:YES]; - // Tap the back button, stop pending navigation and reload. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], - @"Last request URL: %@", self.lastRequestURLSpec); - // On iPhone Stop/Reload button is a part of tools menu, so open it. - if (![ChromeEarlGrey isIPadIdiom]) { - // Enable EG synchronization to make test wait for popover animations. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - [ChromeEarlGreyUI openToolsMenu]; + // Tap the back button, stop pending navigation and reload. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], + @"Last request URL: %@", self.lastRequestURLSpec); + // On iPhone Stop/Reload button is a part of tools menu, so open it. + if (![ChromeEarlGrey isIPadIdiom]) { + // Enable EG synchronization to make test wait for popover animations. + disabler.reset(); + [ChromeEarlGreyUI openToolsMenu]; + } + [[EarlGrey selectElementWithMatcher:chrome_test_util::StopButton()] + performAction:grey_tap()]; + [ChromeEarlGreyUI reload]; + + // Makes server respond. + [self setServerPaused:NO]; } - [[EarlGrey selectElementWithMatcher:chrome_test_util::StopButton()] - performAction:grey_tap()]; - [ChromeEarlGreyUI reload]; - - // Make server respond and verify that page2 was reloaded, not page1. - [self setServerPaused:NO]; + // Verifies that page2 was reloaded, not page1. [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] assertWithMatcher:grey_notNil()]; @@ -304,19 +310,24 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the back button on the page and verify that URL2 (committed URL) is - // displayed even though URL1 is a pending URL. - [ChromeEarlGrey - tapWebStateElementWithID:base::SysUTF8ToNSString(kGoBackLink)]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the back button on the page and verify that URL2 (committed URL) is + // displayed even though URL1 is a pending URL. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kGoBackLink)]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -325,19 +336,24 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the forward button on the page and verify that URL1 (committed URL) - // is displayed even though URL2 is a pending URL. - [ChromeEarlGrey - tapWebStateElementWithID:base::SysUTF8ToNSString(kGoForwardLink)]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL2], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the forward button on the page and verify that URL1 (committed URL) + // is displayed even though URL2 is a pending URL. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kGoForwardLink)]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL2], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL2 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL2 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] assertWithMatcher:grey_notNil()]; @@ -354,19 +370,24 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the go negative delta button on the page and verify that URL2 - // (committed URL) is displayed even though URL1 is a pending URL. - [ChromeEarlGrey - tapWebStateElementWithID:base::SysUTF8ToNSString(kGoNegativeDeltaLink)]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the go negative delta button on the page and verify that URL2 + // (committed URL) is displayed even though URL1 is a pending URL. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kGoNegativeDeltaLink)]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -375,19 +396,24 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap go positive delta button on the page and verify that URL1 (committed - // URL) is displayed even though URL2 is a pending URL. - [ChromeEarlGrey - tapWebStateElementWithID:base::SysUTF8ToNSString(kGoPositiveDeltaLink)]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL2], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap go positive delta button on the page and verify that URL1 (committed + // URL) is displayed even though URL2 is a pending URL. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kGoPositiveDeltaLink)]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL2], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL2 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL2 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] assertWithMatcher:grey_notNil()]; @@ -404,31 +430,34 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + std::unique_ptr<ScopedSynchronizationDisabler> disabler = + std::make_unique<ScopedSynchronizationDisabler>(); - // Start reloading the page. - if (![ChromeEarlGrey isIPadIdiom]) { - // Enable EG synchronization to make test wait for popover animations. - [[GREYConfiguration sharedInstance] - setValue:@YES - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - [ChromeEarlGreyUI openToolsMenu]; + [self setServerPaused:YES]; + + // Start reloading the page. + if (![ChromeEarlGrey isIPadIdiom]) { + // Enable EG synchronization to make test wait for popover animations. + disabler.reset(); + [ChromeEarlGreyUI openToolsMenu]; + } + [[EarlGrey selectElementWithMatcher:chrome_test_util::ReloadButton()] + performAction:grey_tap()]; + + // Do not wait until reload is finished, tap the back button in the toolbar + // and verify that URL2 (committed URL) is displayed even though URL1 is a + // pending URL. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + // TODO(crbug.com/724560): Re-evaluate if necessary to check receiving URL1 + // request here. + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; + + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; } - [[EarlGrey selectElementWithMatcher:chrome_test_util::ReloadButton()] - performAction:grey_tap()]; - - // Do not wait until reload is finished, tap the back button in the toolbar - // and verify that URL2 (committed URL) is displayed even though URL1 is a - // pending URL. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - // TODO(crbug.com/724560): Re-evaluate if necessary to check receiving URL1 - // request here. - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; - - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -453,23 +482,29 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Start renderer initiated navigation. - [ChromeEarlGrey tapWebStateElementWithID:base::SysUTF8ToNSString(kPage3Link)]; + // Start renderer initiated navigation. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kPage3Link)]; - // Do not wait until renderer-initiated navigation is finished, tap the back - // button in the toolbar and verify that URL2 (committed URL) is displayed - // even though URL1 is a pending URL. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - // TODO(crbug.com/724560): Re-evaluate if necessary to check receiving URL1 - // request here. - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; + // Do not wait until renderer-initiated navigation is finished, tap the back + // button in the toolbar and verify that URL2 (committed URL) is displayed + // even though URL1 is a pending URL. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + // TODO(crbug.com/724560): Re-evaluate if necessary to check receiving URL1 + // request here. + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -487,24 +522,30 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage2]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the back button in the toolbar and verify that URL2 (committed URL) is - // displayed even though URL1 is a pending URL. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], - @"Last request URL: %@", self.lastRequestURLSpec); - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the back button in the toolbar and verify that URL2 (committed URL) + // is displayed even though URL1 is a pending URL. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + GREYAssert([self waitForServerToReceiveRequestWithURL:_testURL1], + @"Last request URL: %@", self.lastRequestURLSpec); + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - // Interrupt back navigation with renderer initiated navigation. - [ChromeEarlGrey tapWebStateElementWithID:base::SysUTF8ToNSString(kPage3Link)]; - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] - assertWithMatcher:grey_notNil()]; + // Interrupt back navigation with renderer initiated navigation. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kPage3Link)]; + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL2.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage3]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL3.GetContent())] assertWithMatcher:grey_notNil()]; @@ -524,22 +565,27 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage3]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the back button twice in the toolbar and verify that URL3 (committed - // URL) is displayed even though URL1 is a pending URL. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - performAction:grey_tap()]; - // Server will receive only one request either for |_testURL2| or for - // |_testURL1| depending on load timing and then will pause. So there is no - // need to wait for particular request. - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL3.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the back button twice in the toolbar and verify that URL3 (committed + // URL) is displayed even though URL1 is a pending URL. + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] + performAction:grey_tap()]; + // Server will receive only one request either for |_testURL2| or for + // |_testURL1| depending on load timing and then will pause. So there is no + // need to wait for particular request. + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL3.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] assertWithMatcher:grey_notNil()]; @@ -590,22 +636,27 @@ // verify omnibox state before server starts responding. GREYAssert(PurgeCachedWebViewPages(), @"Pages were not purged"); [ChromeEarlGrey waitForWebStateContainingText:kTestPage3]; - [self setServerPaused:YES]; + { + // Pauses response server and disables EG synchronization. + // Pending navigation will not complete until server is unpaused. + ScopedSynchronizationDisabler disabler; + [self setServerPaused:YES]; - // Tap the back button twice on the page and verify that URL3 (committed URL) - // is displayed even though URL1 is a pending URL. - [ChromeEarlGrey - tapWebStateElementWithID:base::SysUTF8ToNSString(kGoBackLink)]; - [ChromeEarlGrey - tapWebStateElementWithID:base::SysUTF8ToNSString(kGoBackLink)]; - // Server will receive only one request either for |_testURL2| or for - // |_testURL1| depending on load timing and then will pause. So there is no - // need to wait for particular request. - [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL3.GetContent())] - assertWithMatcher:grey_notNil()]; + // Tap the back button twice on the page and verify that URL3 (committed + // URL) is displayed even though URL1 is a pending URL. + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kGoBackLink)]; + [ChromeEarlGrey + tapWebStateElementWithID:base::SysUTF8ToNSString(kGoBackLink)]; + // Server will receive only one request either for |_testURL2| or for + // |_testURL1| depending on load timing and then will pause. So there is no + // need to wait for particular request. + [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL3.GetContent())] + assertWithMatcher:grey_notNil()]; - // Make server respond so URL1 becomes committed. - [self setServerPaused:NO]; + // Make server respond so URL1 becomes committed. + [self setServerPaused:NO]; + } // TODO(crbug.com/866406): fix the test to have documented behavior. [ChromeEarlGrey waitForWebStateContainingText:kTestPage1]; [[EarlGrey selectElementWithMatcher:OmniboxText(_testURL1.GetContent())] @@ -620,14 +671,6 @@ } - (void)setServerPaused:(BOOL)paused { - // Disable EG synchronization if server is paused so the framework does not - // wait until the tab loading spinner or progress bar indicator becomes idle - // (which will not happen until server responds and the navigation is - // finished). - [[GREYConfiguration sharedInstance] - setValue:@(!paused) - forConfigKey:kGREYConfigKeySynchronizationEnabled]; - _responseProvider->set_paused(paused); }
diff --git a/ios/chrome/common/colors/resources/BUILD.gn b/ios/chrome/common/colors/resources/BUILD.gn index 3557e64cc7..5d5393e 100644 --- a/ios/chrome/common/colors/resources/BUILD.gn +++ b/ios/chrome/common/colors/resources/BUILD.gn
@@ -32,6 +32,9 @@ ":textfield_background_dark_color", ":textfield_placeholder_color", ":textfield_placeholder_dark_color", + ":toolbar_button_color", + ":toolbar_button_dark_color", + ":toolbar_shadow_color", ] } @@ -59,6 +62,18 @@ ] } +colorset("close_button_color") { + sources = [ + "close_button_color.colorset/Contents.json", + ] +} + +colorset("close_button_dark_color") { + sources = [ + "close_button_dark_color.colorset/Contents.json", + ] +} + colorset("disabled_tint_color") { sources = [ "disabled_tint_color.colorset/Contents.json", @@ -178,14 +193,21 @@ "textfield_background_dark_color.colorset/Contents.json", ] } -colorset("close_button_color") { + +colorset("toolbar_button_color") { sources = [ - "close_button_color.colorset/Contents.json", + "toolbar_button_color.colorset/Contents.json", ] } -colorset("close_button_dark_color") { +colorset("toolbar_button_dark_color") { sources = [ - "close_button_dark_color.colorset/Contents.json", + "toolbar_button_dark_color.colorset/Contents.json", + ] +} + +colorset("toolbar_shadow_color") { + sources = [ + "toolbar_shadow_color.colorset/Contents.json", ] }
diff --git a/ios/chrome/browser/ui/toolbar/buttons/resources/tab_toolbar_button_color.colorset/Contents.json b/ios/chrome/common/colors/resources/toolbar_button_color.colorset/Contents.json similarity index 100% rename from ios/chrome/browser/ui/toolbar/buttons/resources/tab_toolbar_button_color.colorset/Contents.json rename to ios/chrome/common/colors/resources/toolbar_button_color.colorset/Contents.json
diff --git a/ios/chrome/browser/ui/toolbar/buttons/resources/tab_toolbar_button_color_incognito.colorset/Contents.json b/ios/chrome/common/colors/resources/toolbar_button_dark_color.colorset/Contents.json similarity index 100% rename from ios/chrome/browser/ui/toolbar/buttons/resources/tab_toolbar_button_color_incognito.colorset/Contents.json rename to ios/chrome/common/colors/resources/toolbar_button_dark_color.colorset/Contents.json
diff --git a/ios/chrome/browser/ui/toolbar/resources/tab_toolbar_shadow_color.colorset/Contents.json b/ios/chrome/common/colors/resources/toolbar_shadow_color.colorset/Contents.json similarity index 100% rename from ios/chrome/browser/ui/toolbar/resources/tab_toolbar_shadow_color.colorset/Contents.json rename to ios/chrome/common/colors/resources/toolbar_shadow_color.colorset/Contents.json
diff --git a/ios/chrome/common/colors/semantic_color_names.h b/ios/chrome/common/colors/semantic_color_names.h index bb4b2bd3..1c84a92 100644 --- a/ios/chrome/common/colors/semantic_color_names.h +++ b/ios/chrome/common/colors/semantic_color_names.h
@@ -24,6 +24,10 @@ extern NSString* const kTextSecondaryColor; extern NSString* const kTextfieldBackgroundColor; extern NSString* const kTextfieldPlaceholderColor; +// Color used for buttons on a toolbar. +extern NSString* const kToolbarButtonColor; +// Color used for a shadow/separator next to a toolbar. +extern NSString* const kToolbarShadowColor; // Standard Colors @@ -48,6 +52,7 @@ extern NSString* const kTextSecondaryDarkColor; extern NSString* const kTextfieldBackgroundDarkColor; extern NSString* const kTextfieldPlaceholderDarkColor; +extern NSString* const kToolbarButtonDarkColor; extern NSString* const kBlueDarkColor; extern NSString* const kGreenDarkColor;
diff --git a/ios/chrome/common/colors/semantic_color_names.mm b/ios/chrome/common/colors/semantic_color_names.mm index 4a612ab..cbb7098 100644 --- a/ios/chrome/common/colors/semantic_color_names.mm +++ b/ios/chrome/common/colors/semantic_color_names.mm
@@ -22,6 +22,8 @@ NSString* const kTextSecondaryColor = @"text_secondary_color"; NSString* const kTextfieldBackgroundColor = @"textfield_background_color"; NSString* const kTextfieldPlaceholderColor = @"textfield_placeholder_color"; +NSString* const kToolbarButtonColor = @"toolbar_button_color"; +NSString* const kToolbarShadowColor = @"toolbar_shadow_color"; #pragma mark - Standard Colors NSString* const kBlueColor = @"blue_color"; @@ -40,6 +42,7 @@ @"textfield_background_dark_color"; NSString* const kTextfieldPlaceholderDarkColor = @"textfield_placeholder_dark_color"; +NSString* const kToolbarButtonDarkColor = @"toolbar_button_dark_color"; NSString* const kBlueDarkColor = @"blue_dark_color"; NSString* const kGreenDarkColor = @"green_dark_color";
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index 7cf6f02..28093ca 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -43,6 +43,10 @@ // Returns YES if running on an iPad. - (BOOL)isIPadIdiom; +// Returns YES if the main application window's rootViewController has a compact +// horizontal size class. +- (BOOL)isCompactWidth; + #pragma mark - History Utilities (EG2) // Clears browsing history. Raises an EarlGrey exception if history is not // cleared within a timeout.
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index 7ccbf94..91d3df4 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -66,6 +66,19 @@ return idiom == UIUserInterfaceIdiomPad; } +- (BOOL)isCompactWidth { +#if defined(CHROME_EARL_GREY_1) + UIUserInterfaceSizeClass horizontalSpace = + [[[[UIApplication sharedApplication] keyWindow] traitCollection] + horizontalSizeClass]; +#elif defined(CHROME_EARL_GREY_2) + UIUserInterfaceSizeClass horizontalSpace = + [[[[GREY_REMOTE_CLASS_IN_APP(UIApplication) sharedApplication] keyWindow] + traitCollection] horizontalSizeClass]; +#endif + return horizontalSpace == UIUserInterfaceSizeClassCompact; +} + #pragma mark - History Utilities (EG2) - (void)clearBrowsingHistory {
diff --git a/ios/chrome/test/earl_grey2/smoke_egtest.mm b/ios/chrome/test/earl_grey2/smoke_egtest.mm index 611d9db..757ad20 100644 --- a/ios/chrome/test/earl_grey2/smoke_egtest.mm +++ b/ios/chrome/test/earl_grey2/smoke_egtest.mm
@@ -210,4 +210,15 @@ @"SlimNavigationManager should be enabled"); } +// Tests isCompactWidth method in chrome_earl_grey.h. +- (void)testisCompactWidth { + BOOL expectedIsCompactWidth = + [[[[GREY_REMOTE_CLASS_IN_APP(UIApplication) sharedApplication] keyWindow] + traitCollection] horizontalSizeClass] == + UIUserInterfaceSizeClassCompact; + GREYAssertTrue([ChromeEarlGrey isCompactWidth] == expectedIsCompactWidth, + @"isCompactWidth should return %@", + expectedIsCompactWidth ? @"YES" : @"NO"); +} + @end
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.h b/ios/public/provider/chrome/browser/chrome_browser_provider.h index dbef8f3..e4bff13d 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.h +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.h
@@ -108,7 +108,9 @@ virtual GeolocationUpdaterProvider* GetGeolocationUpdaterProvider(); // Returns risk data used in Wallet requests. virtual std::string GetRiskData(); - // Creates and returns a new styled text field with the given |frame|. + // Creates and returns a new styled text field. + virtual UITextField* CreateStyledTextField() const NS_RETURNS_RETAINED; + // Deprecated. virtual UITextField<TextFieldStyling>* CreateStyledTextField( CGRect frame) const NS_RETURNS_RETAINED;
diff --git a/ios/public/provider/chrome/browser/chrome_browser_provider.mm b/ios/public/provider/chrome/browser/chrome_browser_provider.mm index 1cf0fd5..6c5c9ab 100644 --- a/ios/public/provider/chrome/browser/chrome_browser_provider.mm +++ b/ios/public/provider/chrome/browser/chrome_browser_provider.mm
@@ -68,6 +68,10 @@ return std::string(); } +UITextField* ChromeBrowserProvider::CreateStyledTextField() const { + return nil; +} + UITextField<TextFieldStyling>* ChromeBrowserProvider::CreateStyledTextField( CGRect frame) const { return nil;
diff --git a/ios/public/provider/chrome/browser/test_chrome_browser_provider.h b/ios/public/provider/chrome/browser/test_chrome_browser_provider.h index e589774..a4a5b75 100644 --- a/ios/public/provider/chrome/browser/test_chrome_browser_provider.h +++ b/ios/public/provider/chrome/browser/test_chrome_browser_provider.h
@@ -26,6 +26,7 @@ void SetChromeIdentityServiceForTesting( std::unique_ptr<ChromeIdentityService> service) override; ChromeIdentityService* GetChromeIdentityService() override; + UITextField* CreateStyledTextField() const override NS_RETURNS_RETAINED; UITextField<TextFieldStyling>* CreateStyledTextField( CGRect frame) const override NS_RETURNS_RETAINED; VoiceSearchProvider* GetVoiceSearchProvider() const override;
diff --git a/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm b/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm index c2bad88..b34b2cd9 100644 --- a/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm +++ b/ios/public/provider/chrome/browser/test_chrome_browser_provider.mm
@@ -67,6 +67,10 @@ return chrome_identity_service_.get(); } +UITextField* TestChromeBrowserProvider::CreateStyledTextField() const { + return [[UITextField alloc] initWithFrame:CGRectZero]; +} + UITextField<TextFieldStyling>* TestChromeBrowserProvider::CreateStyledTextField( CGRect frame) const { return [[TestStyledTextField alloc] initWithFrame:frame];
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 3a22fdee..2034e1bd 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -375,3 +375,13 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_enable_lifo_write_scheduler, false) + +// When true, remove obsolete functionality intended to test IETF QUIC recovery. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_sent_packet_manager_cleanup, + false) + +// If true, QUIC will track max ack height in BandwidthSampler. +QUIC_FLAG(bool, + FLAGS_quic_reloadable_flag_quic_track_ack_height_in_bandwidth_sampler, + false)
diff --git a/pdf/draw_utils/coordinates.cc b/pdf/draw_utils/coordinates.cc index 4a62020..ef760be 100644 --- a/pdf/draw_utils/coordinates.cc +++ b/pdf/draw_utils/coordinates.cc
@@ -55,39 +55,6 @@ return two_up_insets; } -pp::Rect GetLeftFillRect(const pp::Rect& page_rect, - const PageInsetSizes& inset_sizes, - int bottom_separator) { - DCHECK_GE(page_rect.x(), inset_sizes.left); - - return pp::Rect(0, page_rect.y() - inset_sizes.top, - page_rect.x() - inset_sizes.left, - page_rect.height() + inset_sizes.top + inset_sizes.bottom + - bottom_separator); -} - -pp::Rect GetRightFillRect(const pp::Rect& page_rect, - const PageInsetSizes& inset_sizes, - int doc_width, - int bottom_separator) { - int right_gap_x = page_rect.right() + inset_sizes.right; - DCHECK_GE(doc_width, right_gap_x); - - return pp::Rect(right_gap_x, page_rect.y() - inset_sizes.top, - doc_width - right_gap_x, - page_rect.height() + inset_sizes.top + inset_sizes.bottom + - bottom_separator); -} - -pp::Rect GetBottomFillRect(const pp::Rect& page_rect, - const PageInsetSizes& inset_sizes, - int bottom_separator) { - return pp::Rect(page_rect.x() - inset_sizes.left, - page_rect.bottom() + inset_sizes.bottom, - page_rect.width() + inset_sizes.left + inset_sizes.right, - bottom_separator); -} - pp::Rect GetRectForSingleView(const pp::Size& rect_size, const pp::Size& document_size, const PageInsetSizes& page_insets) { @@ -121,6 +88,39 @@ page_height + inset_sizes.top + inset_sizes.bottom + bottom_separator); } +pp::Rect GetLeftFillRect(const pp::Rect& page_rect, + const PageInsetSizes& inset_sizes, + int bottom_separator) { + DCHECK_GE(page_rect.x(), inset_sizes.left); + + return pp::Rect(0, page_rect.y() - inset_sizes.top, + page_rect.x() - inset_sizes.left, + page_rect.height() + inset_sizes.top + inset_sizes.bottom + + bottom_separator); +} + +pp::Rect GetRightFillRect(const pp::Rect& page_rect, + const PageInsetSizes& inset_sizes, + int doc_width, + int bottom_separator) { + int right_gap_x = page_rect.right() + inset_sizes.right; + DCHECK_GE(doc_width, right_gap_x); + + return pp::Rect(right_gap_x, page_rect.y() - inset_sizes.top, + doc_width - right_gap_x, + page_rect.height() + inset_sizes.top + inset_sizes.bottom + + bottom_separator); +} + +pp::Rect GetBottomFillRect(const pp::Rect& page_rect, + const PageInsetSizes& inset_sizes, + int bottom_separator) { + return pp::Rect(page_rect.x() - inset_sizes.left, + page_rect.bottom() + inset_sizes.bottom, + page_rect.width() + inset_sizes.left + inset_sizes.right, + bottom_separator); +} + pp::Rect GetLeftRectForTwoUpView(const pp::Size& rect_size, const pp::Point& position, const PageInsetSizes& page_insets) {
diff --git a/pdf/draw_utils/coordinates.h b/pdf/draw_utils/coordinates.h index 1a77b49..f6a4115 100644 --- a/pdf/draw_utils/coordinates.h +++ b/pdf/draw_utils/coordinates.h
@@ -57,31 +57,6 @@ const PageInsetSizes& single_view_insets, int horizontal_separator); -// TODO (chinsenj): move Get*FillRect() functions to bottom of coordinates.h. -// Given |page_rect| in document coordinates, |inset_sizes|, and -// |bottom_separator|, return a pp::Rect object representing the gap on the -// left side of the page created by insetting the page. I.e. the difference, -// on the left side, between the initial |page_rect| and the |page_rect| inset -// with |inset_sizes| (current value of |page_rect|). -// The x coordinate of |page_rect| must be greater than or equal to -// |inset_sizes.left|. -pp::Rect GetLeftFillRect(const pp::Rect& page_rect, - const PageInsetSizes& inset_sizes, - int bottom_separator); - -// Same as GetLeftFillRect(), but for the right side of |page_rect| and also -// depends on the |doc_width|. Additionally, |doc_width| must be greater than or -// equal to the sum of |page_rect.right| and |inset_sizes.right|. -pp::Rect GetRightFillRect(const pp::Rect& page_rect, - const PageInsetSizes& inset_sizes, - int doc_width, - int bottom_separator); - -// Same as GetLeftFillRect(), but for the bottom side of |page_rect|. -pp::Rect GetBottomFillRect(const pp::Rect& page_rect, - const PageInsetSizes& inset_sizes, - int bottom_separator); - // Given |rect_size| and |document_size| create a horizontally centered // pp::Rect placed at the bottom of the current document, and then inset it with // |page_insets|. @@ -108,6 +83,30 @@ int doc_width, int bottom_separator); +// Given |page_rect| in document coordinates, |inset_sizes|, and +// |bottom_separator|, return a pp::Rect object representing the gap on the +// left side of the page created by insetting the page. I.e. the difference, +// on the left side, between the initial |page_rect| and the |page_rect| inset +// with |inset_sizes| (current value of |page_rect|). +// The x coordinate of |page_rect| must be greater than or equal to +// |inset_sizes.left|. +pp::Rect GetLeftFillRect(const pp::Rect& page_rect, + const PageInsetSizes& inset_sizes, + int bottom_separator); + +// Same as GetLeftFillRect(), but for the right side of |page_rect| and also +// depends on the |doc_width|. Additionally, |doc_width| must be greater than or +// equal to the sum of |page_rect.right| and |inset_sizes.right|. +pp::Rect GetRightFillRect(const pp::Rect& page_rect, + const PageInsetSizes& inset_sizes, + int doc_width, + int bottom_separator); + +// Same as GetLeftFillRect(), but for the bottom side of |page_rect|. +pp::Rect GetBottomFillRect(const pp::Rect& page_rect, + const PageInsetSizes& inset_sizes, + int bottom_separator); + // Given |rect_size|, create a pp::Rect where the top-right corner lies at // |position|, and then inset it with the corresponding values of |page_insets|, // i.e. inset on left side with |page_insets.left|.
diff --git a/pdf/draw_utils/coordinates_unittest.cc b/pdf/draw_utils/coordinates_unittest.cc index ed221b8..1618f65 100644 --- a/pdf/draw_utils/coordinates_unittest.cc +++ b/pdf/draw_utils/coordinates_unittest.cc
@@ -126,6 +126,63 @@ GetPageInsetsForTwoUpView(1, 4, kSingleViewInsets, kHorizontalSeparator)); } +TEST(CoordinateTest, GetRectForSingleView) { + // Test portrait pages. + CompareRect({55, 503, 190, 390}, + GetRectForSingleView({200, 400}, {300, 500}, kSingleViewInsets)); + CompareRect({55, 603, 90, 330}, + GetRectForSingleView({100, 340}, {200, 600}, kSingleViewInsets)); + + // Test landscape pages. + CompareRect({5, 1003, 490, 440}, + GetRectForSingleView({500, 450}, {500, 1000}, kSingleViewInsets)); + CompareRect({30, 1503, 640, 190}, + GetRectForSingleView({650, 200}, {700, 1500}, kSingleViewInsets)); +} + +TEST(CoordinateTest, GetScreenRect) { + const pp::Rect rect(10, 20, 200, 300); + + // Test various zooms with the position at the origin. + CompareRect({10, 20, 200, 300}, GetScreenRect(rect, {0, 0}, 1)); + CompareRect({15, 30, 300, 450}, GetScreenRect(rect, {0, 0}, 1.5)); + CompareRect({5, 10, 100, 150}, GetScreenRect(rect, {0, 0}, 0.5)); + + // Test various zooms with the position elsewhere. + CompareRect({-390, -10, 200, 300}, GetScreenRect(rect, {400, 30}, 1)); + CompareRect({-385, 0, 300, 450}, GetScreenRect(rect, {400, 30}, 1.5)); + CompareRect({-395, -20, 100, 150}, GetScreenRect(rect, {400, 30}, 0.5)); + + // Test various zooms with a negative position. + CompareRect({-90, 70, 200, 300}, GetScreenRect(rect, {100, -50}, 1)); + CompareRect({-85, 80, 300, 450}, GetScreenRect(rect, {100, -50}, 1.5)); + CompareRect({-95, 60, 100, 150}, GetScreenRect(rect, {100, -50}, 0.5)); + + // Test an empty rect always outputs an empty rect. + const pp::Rect empty_rect; + CompareRect({-20, -500, 0, 0}, GetScreenRect(empty_rect, {20, 500}, 1)); + CompareRect({-20, -500, 0, 0}, GetScreenRect(empty_rect, {20, 500}, 1.5)); + CompareRect({-20, -500, 0, 0}, GetScreenRect(empty_rect, {20, 500}, 0.5)); +} + +TEST(CoordinateTest, GetSurroundingRect) { + constexpr int kDocWidth = 1000; + + // Test various position, sizes, and document width. + CompareRect({0, 97, 1000, 314}, + GetSurroundingRect(100, 300, kSingleViewInsets, kDocWidth, + kBottomSeparator)); + CompareRect({0, 37, 1000, 214}, + GetSurroundingRect(40, 200, kSingleViewInsets, kDocWidth, + kBottomSeparator)); + CompareRect({0, 197, 1000, 514}, + GetSurroundingRect(200, 500, kSingleViewInsets, kDocWidth, + kBottomSeparator)); + CompareRect( + {0, -103, 200, 314}, + GetSurroundingRect(-100, 300, kSingleViewInsets, 200, kBottomSeparator)); +} + TEST(CoordinateTest, GetLeftFillRect) { // Testing various rectangles with different positions and sizes. pp::Rect page_rect(10, 20, 400, 500); @@ -194,63 +251,6 @@ kBottomSeparator)); } -TEST(CoordinateTest, GetRectForSingleView) { - // Test portrait pages. - CompareRect({55, 503, 190, 390}, - GetRectForSingleView({200, 400}, {300, 500}, kSingleViewInsets)); - CompareRect({55, 603, 90, 330}, - GetRectForSingleView({100, 340}, {200, 600}, kSingleViewInsets)); - - // Test landscape pages. - CompareRect({5, 1003, 490, 440}, - GetRectForSingleView({500, 450}, {500, 1000}, kSingleViewInsets)); - CompareRect({30, 1503, 640, 190}, - GetRectForSingleView({650, 200}, {700, 1500}, kSingleViewInsets)); -} - -TEST(CoordinateTest, GetScreenRect) { - const pp::Rect rect(10, 20, 200, 300); - - // Test various zooms with the position at the origin. - CompareRect({10, 20, 200, 300}, GetScreenRect(rect, {0, 0}, 1)); - CompareRect({15, 30, 300, 450}, GetScreenRect(rect, {0, 0}, 1.5)); - CompareRect({5, 10, 100, 150}, GetScreenRect(rect, {0, 0}, 0.5)); - - // Test various zooms with the position elsewhere. - CompareRect({-390, -10, 200, 300}, GetScreenRect(rect, {400, 30}, 1)); - CompareRect({-385, 0, 300, 450}, GetScreenRect(rect, {400, 30}, 1.5)); - CompareRect({-395, -20, 100, 150}, GetScreenRect(rect, {400, 30}, 0.5)); - - // Test various zooms with a negative position. - CompareRect({-90, 70, 200, 300}, GetScreenRect(rect, {100, -50}, 1)); - CompareRect({-85, 80, 300, 450}, GetScreenRect(rect, {100, -50}, 1.5)); - CompareRect({-95, 60, 100, 150}, GetScreenRect(rect, {100, -50}, 0.5)); - - // Test an empty rect always outputs an empty rect. - const pp::Rect empty_rect; - CompareRect({-20, -500, 0, 0}, GetScreenRect(empty_rect, {20, 500}, 1)); - CompareRect({-20, -500, 0, 0}, GetScreenRect(empty_rect, {20, 500}, 1.5)); - CompareRect({-20, -500, 0, 0}, GetScreenRect(empty_rect, {20, 500}, 0.5)); -} - -TEST(CoordinateTest, GetSurroundingRect) { - constexpr int kDocWidth = 1000; - - // Test various position, sizes, and document width. - CompareRect({0, 97, 1000, 314}, - GetSurroundingRect(100, 300, kSingleViewInsets, kDocWidth, - kBottomSeparator)); - CompareRect({0, 37, 1000, 214}, - GetSurroundingRect(40, 200, kSingleViewInsets, kDocWidth, - kBottomSeparator)); - CompareRect({0, 197, 1000, 514}, - GetSurroundingRect(200, 500, kSingleViewInsets, kDocWidth, - kBottomSeparator)); - CompareRect( - {0, -103, 200, 314}, - GetSurroundingRect(-100, 300, kSingleViewInsets, 200, kBottomSeparator)); -} - TEST(CoordinateTest, GetLeftRectForTwoUpView) { CompareRect({105, 103, 194, 390}, GetLeftRectForTwoUpView({200, 400}, {300, 100}, kLeftInsets)); @@ -281,34 +281,5 @@ GetRightRectForTwoUpView({0, 0}, {100, 0}, kRightInsets)); } -TEST(CoordinateTest, TwoUpViewLayout) { - pp::Point position(1066, 0); - - // Test layout when the widest page is on the left. - CompareRect({245, 3, 820, 1056}, - GetLeftRectForTwoUpView({826, 1066}, position, kLeftInsets)); - CompareRect({1067, 3, 1060, 816}, - GetRightRectForTwoUpView({1066, 826}, position, kRightInsets)); - - position.set_y(1066); - CompareRect({245, 1069, 820, 1056}, - GetLeftRectForTwoUpView({826, 1066}, position, kLeftInsets)); - CompareRect({1067, 1069, 820, 890}, - GetRightRectForTwoUpView({826, 900}, position, kRightInsets)); - - // Test layout when the widest page is on the right. - position.set_y(0); - CompareRect({5, 3, 1060, 816}, - GetLeftRectForTwoUpView({1066, 826}, position, kLeftInsets)); - CompareRect({1067, 3, 820, 1056}, - GetRightRectForTwoUpView({826, 1066}, position, kRightInsets)); - - position.set_y(1066); - CompareRect({245, 1069, 820, 890}, - GetLeftRectForTwoUpView({826, 900}, position, kLeftInsets)); - CompareRect({1067, 1069, 820, 1056}, - GetRightRectForTwoUpView({826, 1066}, position, kRightInsets)); -} - } // namespace draw_utils } // namespace chrome_pdf
diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc index 2563ae6..17c363f 100644 --- a/printing/print_settings_conversion.cc +++ b/printing/print_settings_conversion.cc
@@ -25,21 +25,19 @@ namespace { -void GetCustomMarginsFromJobSettings(const base::Value& settings, - PageMargins* page_size_margins) { +// Note: If this code crashes, then the caller has passed in invalid |settings|. +// Fix the caller, instead of trying to avoid the crash here. +PageMargins GetCustomMarginsFromJobSettings(const base::Value& settings) { + PageMargins margins_in_points; const base::Value* custom_margins = settings.FindKey(kSettingMarginsCustom); - if (!custom_margins) { - NOTREACHED(); - return; - } - page_size_margins->top = - custom_margins->FindIntKey(kSettingMarginTop).value_or(0); - page_size_margins->bottom = - custom_margins->FindIntKey(kSettingMarginBottom).value_or(0); - page_size_margins->left = - custom_margins->FindIntKey(kSettingMarginLeft).value_or(0); - page_size_margins->right = - custom_margins->FindIntKey(kSettingMarginRight).value_or(0); + margins_in_points.top = custom_margins->FindIntKey(kSettingMarginTop).value(); + margins_in_points.bottom = + custom_margins->FindIntKey(kSettingMarginBottom).value(); + margins_in_points.left = + custom_margins->FindIntKey(kSettingMarginLeft).value(); + margins_in_points.right = + custom_margins->FindIntKey(kSettingMarginRight).value(); + return margins_in_points; } void SetMarginsToJobSettings(const std::string& json_path, @@ -133,12 +131,8 @@ } settings->set_margin_type(static_cast<MarginType>(margin_type)); - if (margin_type == CUSTOM_MARGINS) { - PageMargins margins_in_points; - margins_in_points.Clear(); - GetCustomMarginsFromJobSettings(job_settings, &margins_in_points); - settings->SetCustomMargins(margins_in_points); - } + if (margin_type == CUSTOM_MARGINS) + settings->SetCustomMargins(GetCustomMarginsFromJobSettings(job_settings)); PageRanges new_ranges; const base::Value* page_range_array =
diff --git a/services/tracing/public/cpp/perfetto/perfetto_producer.cc b/services/tracing/public/cpp/perfetto/perfetto_producer.cc index ee87551..9d0a0f88 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_producer.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_producer.cc
@@ -28,7 +28,14 @@ std::unique_ptr<perfetto::TraceWriter> PerfettoProducer::CreateTraceWriter( perfetto::BufferID target_buffer) { DCHECK(GetSharedMemoryArbiter()); - return GetSharedMemoryArbiter()->CreateTraceWriter(target_buffer); + // Chromium uses BufferExhaustedPolicy::kDrop to avoid stalling trace writers + // when the chunks in the SMB are exhausted. Stalling could otherwise lead to + // deadlocks in chromium, because a stalled mojo IPC thread could prevent + // CommitRequest messages from reaching the perfetto service. + auto smb_exhausted_policy = + perfetto::SharedMemoryArbiter::BufferExhaustedPolicy::kDrop; + return GetSharedMemoryArbiter()->CreateTraceWriter(target_buffer, + smb_exhausted_policy); } PerfettoTaskRunner* PerfettoProducer::task_runner() {
diff --git a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc index 8afe51f..a2e6dae 100644 --- a/services/tracing/public/cpp/perfetto/trace_event_data_source.cc +++ b/services/tracing/public/cpp/perfetto/trace_event_data_source.cc
@@ -539,7 +539,15 @@ std::unique_ptr<perfetto::StartupTraceWriter> trace_writer; uint32_t session_id = session_id_.load(std::memory_order_relaxed); if (startup_writer_registry_) { - trace_writer = startup_writer_registry_->CreateUnboundTraceWriter(); + // Chromium uses BufferExhaustedPolicy::kDrop to avoid stalling trace + // writers when the chunks in the SMB are exhausted. Stalling could + // otherwise lead to deadlocks in chromium, because a stalled mojo IPC + // thread could prevent CommitRequest messages from reaching the perfetto + // service. + auto smb_exhausted_policy = + perfetto::SharedMemoryArbiter::BufferExhaustedPolicy::kDrop; + trace_writer = startup_writer_registry_->CreateUnboundTraceWriter( + smb_exhausted_policy); } else if (producer_) { trace_writer = std::make_unique<perfetto::StartupTraceWriter>( producer_->CreateTraceWriter(target_buffer_));
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 8429987..b1b98b6 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -14573,7 +14573,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14588,7 +14588,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14603,7 +14603,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14618,7 +14618,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14633,7 +14633,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14648,7 +14648,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14663,7 +14663,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14678,7 +14678,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14693,7 +14693,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14708,7 +14708,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14724,7 +14724,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14739,7 +14739,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14754,7 +14754,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14769,7 +14769,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 10 @@ -14790,7 +14790,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14805,7 +14805,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14823,7 +14823,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14838,7 +14838,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14853,7 +14853,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14868,7 +14868,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14883,7 +14883,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14898,7 +14898,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14913,7 +14913,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14928,7 +14928,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14943,7 +14943,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 6 @@ -14964,7 +14964,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14984,7 +14984,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -14999,7 +14999,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15014,7 +15014,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15029,7 +15029,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15044,7 +15044,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15059,7 +15059,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15074,7 +15074,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15089,7 +15089,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15104,7 +15104,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15119,7 +15119,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15134,7 +15134,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15149,7 +15149,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15164,7 +15164,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15179,7 +15179,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15194,7 +15194,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15209,7 +15209,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15224,7 +15224,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15239,7 +15239,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15254,7 +15254,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15269,7 +15269,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15284,7 +15284,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15299,7 +15299,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 3 @@ -15320,7 +15320,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15335,7 +15335,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15350,7 +15350,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15365,7 +15365,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15380,7 +15380,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15395,7 +15395,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15410,7 +15410,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15425,7 +15425,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15440,7 +15440,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15455,7 +15455,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15470,7 +15470,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15485,7 +15485,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15500,7 +15500,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15515,7 +15515,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15530,7 +15530,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15545,7 +15545,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15560,7 +15560,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15575,7 +15575,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15590,7 +15590,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15605,7 +15605,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15620,7 +15620,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15635,7 +15635,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15650,7 +15650,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15665,7 +15665,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15680,7 +15680,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15695,7 +15695,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15710,7 +15710,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15725,7 +15725,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15740,7 +15740,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15755,7 +15755,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15770,7 +15770,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15785,7 +15785,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15800,7 +15800,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15815,7 +15815,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15830,7 +15830,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15845,7 +15845,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15860,7 +15860,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15875,7 +15875,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15890,7 +15890,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15905,7 +15905,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15920,7 +15920,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15935,7 +15935,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15951,7 +15951,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] }, @@ -15970,7 +15970,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -15989,7 +15989,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16005,7 +16005,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16021,7 +16021,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16037,7 +16037,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16053,7 +16053,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16069,7 +16069,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16085,7 +16085,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16101,7 +16101,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16127,7 +16127,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 10 @@ -16161,7 +16161,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16177,7 +16177,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "idempotent": false @@ -16198,7 +16198,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "idempotent": false, @@ -16220,7 +16220,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "idempotent": false, @@ -16243,7 +16243,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16277,7 +16277,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16293,7 +16293,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ] } @@ -16315,7 +16315,7 @@ "can_use_on_swarming_builders": true, "dimension_sets": [ { - "os": "Ubuntu-14.04" + "os": "Ubuntu-16.04" } ], "shards": 12
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 694e35f..062c400 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -24567,7 +24567,8 @@ { "args": [ "../../tools/perf/run_benchmark", - "--benchmarks=rendering.desktop" + "--benchmarks=rendering.desktop", + "--browser=release_x64" ], "experiment_percentage": 100, "isolate_name": "rendering_representative_perf_tests", @@ -25572,7 +25573,8 @@ { "args": [ "../../tools/perf/run_benchmark", - "--benchmarks=rendering.desktop" + "--benchmarks=rendering.desktop", + "--browser=release_x64" ], "experiment_percentage": 100, "isolate_name": "rendering_representative_perf_tests", @@ -27474,7 +27476,8 @@ { "args": [ "../../tools/perf/run_benchmark", - "--benchmarks=rendering.desktop" + "--benchmarks=rendering.desktop", + "--browser=release_x64" ], "experiment_percentage": 100, "isolate_name": "rendering_representative_perf_tests", @@ -28444,7 +28447,8 @@ { "args": [ "../../tools/perf/run_benchmark", - "--benchmarks=rendering.desktop" + "--benchmarks=rendering.desktop", + "--browser=release_x64" ], "experiment_percentage": 100, "isolate_name": "rendering_representative_perf_tests", @@ -30682,7 +30686,8 @@ { "args": [ "../../tools/perf/run_benchmark", - "--benchmarks=rendering.desktop" + "--benchmarks=rendering.desktop", + "--browser=release_x64" ], "experiment_percentage": 100, "isolate_name": "rendering_representative_perf_tests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 494a181..6166511 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1330,6 +1330,35 @@ }, }, }, + 'rendering_representative_perf_tests': { + 'modifications': { + 'Win10 FYI x64 Exp Release (Intel HD 630)': { + 'args': [ + '--browser=release_x64', + ], + }, + 'Win10 FYI x64 Exp Release (NVIDIA)': { + 'args': [ + '--browser=release_x64', + ], + }, + 'Win10 FYI x64 Release (Intel HD 630)': { + 'args': [ + '--browser=release_x64', + ], + }, + 'Win10 FYI x64 Release (Intel UHD 630)': { + 'args': [ + '--browser=release_x64', + ], + }, + 'Win10 FYI x64 Release (NVIDIA)': { + 'args': [ + '--browser=release_x64', + ], + }, + }, + }, 'sandbox_linux_unittests': { 'modifications': { 'Lollipop Phone Tester': {
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index fd5371e..c76948f 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1810,7 +1810,7 @@ }, 'linux-chromium-tests-staging-tests': { 'mixins': [ - 'linux-trusty', + 'linux-xenial', ], 'test_suites': { 'gtest_tests': 'chromium_linux_gtests',
diff --git a/third_party/.gitignore b/third_party/.gitignore index e1b200c7..c21d7d8 100644 --- a/third_party/.gitignore +++ b/third_party/.gitignore
@@ -13,7 +13,6 @@ /android_build_tools/art/profman /android_build_tools/bundletool/*.jar /android_ndk/ -/android_sdk/androidx_browser/src /android_sdk/public/ /android_sdk/sources/ /android_protobuf/src
diff --git a/third_party/android_sdk/androidx_browser/BUILD.gn b/third_party/android_sdk/androidx_browser/BUILD.gn deleted file mode 100644 index 6077716..0000000 --- a/third_party/android_sdk/androidx_browser/BUILD.gn +++ /dev/null
@@ -1,54 +0,0 @@ -# Copyright 2019 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//build/config/android/rules.gni") - -android_resources("androidx_browser_resources") { - resource_dirs = [ "src/browser/src/main/res" ] - custom_package = "android.support.customtabs" -} - -android_library("androidx_browser_java") { - java_files = [ - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabColorSchemeParams.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java", - "./src/browser/src/main/java/androidx/browser/customtabs/PostMessageService.java", - "./src/browser/src/main/java/androidx/browser/customtabs/PostMessageServiceConnection.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsServiceConnection.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsCallback.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsSession.java", - "./src/browser/src/main/java/androidx/browser/customtabs/PostMessageBackend.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsService.java", - "./src/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java", - "./src/browser/src/main/java/androidx/browser/customtabs/TrustedWebUtils.java", - "./src/browser/src/main/java/androidx/browser/trusted/NotificationApiHelperForM.java", - "./src/browser/src/main/java/androidx/browser/trusted/NotificationApiHelperForO.java", - "./src/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityServiceWrapper.java", - "./src/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityServiceConnectionManager.java", - "./src/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityService.java", - "./src/browser/src/main/java/androidx/browser/trusted/TrustedWebActivityBuilder.java", - - ] - deps = [ - ":androidx_browser_resources", - "//third_party/android_deps:android_support_v7_appcompat_java", - "//third_party/android_deps:com_android_support_support_annotations_java", - "//third_party/android_deps:com_android_support_support_compat_java", - ] - srcjar_deps = [ ":androidx_browser_service_aidl" ] - android_manifest_for_lint = "src/browser/src/main/AndroidManifest.xml" - chromium_code = false -} - -android_aidl("androidx_browser_service_aidl") { - interface_file = "common.aidl" - - sources = [ - "./src/browser/src/main/aidl/android/support/customtabs/ICustomTabsService.aidl", - "./src/browser/src/main/aidl/android/support/customtabs/IPostMessageService.aidl", - "./src/browser/src/main/aidl/android/support/customtabs/trusted/ITrustedWebActivityService.aidl", - "./src/browser/src/main/aidl/android/support/customtabs/ICustomTabsCallback.aidl", - ] -}
diff --git a/third_party/android_sdk/androidx_browser/LICENSE b/third_party/android_sdk/androidx_browser/LICENSE deleted file mode 100644 index 67db858..0000000 --- a/third_party/android_sdk/androidx_browser/LICENSE +++ /dev/null
@@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability.
diff --git a/third_party/android_sdk/androidx_browser/OWNERS b/third_party/android_sdk/androidx_browser/OWNERS deleted file mode 100644 index f728cfa..0000000 --- a/third_party/android_sdk/androidx_browser/OWNERS +++ /dev/null
@@ -1,6 +0,0 @@ -lizeb@chromium.org -peconn@chromium.org -yusufo@chromium.org - -per-file *.aidl=set noparent -per-file *.aidl=file://ipc/SECURITY_OWNERS
diff --git a/third_party/android_sdk/androidx_browser/README.chromium b/third_party/android_sdk/androidx_browser/README.chromium deleted file mode 100644 index 27f4bb86..0000000 --- a/third_party/android_sdk/androidx_browser/README.chromium +++ /dev/null
@@ -1,28 +0,0 @@ -Name: AndroidX Browser -Short Name: AndroidX Browser -URL: https://chromium.googlesource.com/external/gob/android/platform/frameworks/support/browser -Version: 226da6c0dfb265404d3a67305802ab70a9ca6c80 -License: Apache 2.0 -Security Critical: yes -License Android Compatible: yes - -Description: -This is a copy of the files from androidx.browser to be used in Chromium. -This covers Custom Tabs and Trusted Web Activities. The original code (not the -Chromium hosted modified copy) can be found at: -https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/browser/ - -Local Modifications: -Since Chromium does not yet rely on AndroidX (it still relies on the Android -Support Library), various parts of androidx.browser have been omitted: -- Browser Actions, which rely on androidx.concurrent.futures.ResolvableFuture. - Chromium has dropped support for Browser Actions so we don't need this code. -- Tests, which rely on androidx.testutils.PollingCheck. New development on - the code in androidx.browser should happen in the AndroidX repository - (and will be automatically copied to the Chromium one). - -In addition, we don't compile with the included AndroidManifest.xml because -in the AndroidX the minSdkVersion is set in build.gradle. Chromium's tooling -can't read this and expects the minSdkVersion to be present in the manifest -(which conversely Android's tooling complains about). If we omit the -AndroidManifest, Chromium's tooling chooses a sensible default.
diff --git a/third_party/android_sdk/androidx_browser/common.aidl b/third_party/android_sdk/androidx_browser/common.aidl deleted file mode 100644 index 0eb2a8a..0000000 --- a/third_party/android_sdk/androidx_browser/common.aidl +++ /dev/null
@@ -1,8 +0,0 @@ -// Copyright 2019 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. - -interface android.support.customtabs.ICustomTabsService; -interface android.support.customtabs.ICustomTabsCallback; -interface android.support.customtabs.IPostMessageService; -interface android.support.customtabs.trusted.ITrustedWebActivityService;
diff --git a/third_party/blink/common/indexeddb/indexed_db_default_mojom_traits.cc b/third_party/blink/common/indexeddb/indexed_db_default_mojom_traits.cc index 702edac..8679107 100644 --- a/third_party/blink/common/indexeddb/indexed_db_default_mojom_traits.cc +++ b/third_party/blink/common/indexeddb/indexed_db_default_mojom_traits.cc
@@ -80,16 +80,15 @@ return blink::mojom::IDBKeyDataDataView::Tag::DATE; case blink::mojom::IDBKeyType::Number: return blink::mojom::IDBKeyDataDataView::Tag::NUMBER; - case blink::mojom::IDBKeyType::Invalid: - return blink::mojom::IDBKeyDataDataView::Tag::OTHER_INVALID; - case blink::mojom::IDBKeyType::Null: - return blink::mojom::IDBKeyDataDataView::Tag::OTHER_NULL; + case blink::mojom::IDBKeyType::None: + return blink::mojom::IDBKeyDataDataView::Tag::OTHER_NONE; // Not used, fall through to NOTREACHED. - case blink::mojom::IDBKeyType::Min:; + case blink::mojom::IDBKeyType::Invalid: // Only used in blink. + case blink::mojom::IDBKeyType::Min:; // Only used in the browser. } NOTREACHED(); - return blink::mojom::IDBKeyDataDataView::Tag::OTHER_INVALID; + return blink::mojom::IDBKeyDataDataView::Tag::OTHER_NONE; } // static @@ -125,11 +124,8 @@ *out = blink::IndexedDBKey(data.number(), blink::mojom::IDBKeyType::Number); return true; - case blink::mojom::IDBKeyDataDataView::Tag::OTHER_INVALID: - *out = blink::IndexedDBKey(blink::mojom::IDBKeyType::Invalid); - return true; - case blink::mojom::IDBKeyDataDataView::Tag::OTHER_NULL: - *out = blink::IndexedDBKey(blink::mojom::IDBKeyType::Null); + case blink::mojom::IDBKeyDataDataView::Tag::OTHER_NONE: + *out = blink::IndexedDBKey(blink::mojom::IDBKeyType::None); return true; }
diff --git a/third_party/blink/common/indexeddb/indexeddb_key.cc b/third_party/blink/common/indexeddb/indexeddb_key.cc index e2fd1e4..99c243e 100644 --- a/third_party/blink/common/indexeddb/indexeddb_key.cc +++ b/third_party/blink/common/indexeddb/indexeddb_key.cc
@@ -34,11 +34,11 @@ } // namespace IndexedDBKey::IndexedDBKey() - : type_(mojom::IDBKeyType::Null), size_estimate_(kOverheadSize) {} + : type_(mojom::IDBKeyType::None), size_estimate_(kOverheadSize) {} IndexedDBKey::IndexedDBKey(mojom::IDBKeyType type) : type_(type), size_estimate_(kOverheadSize) { - DCHECK(type == mojom::IDBKeyType::Null || type == mojom::IDBKeyType::Invalid); + DCHECK(type == mojom::IDBKeyType::None || type == mojom::IDBKeyType::Invalid); } IndexedDBKey::IndexedDBKey(double number, mojom::IDBKeyType type) @@ -71,7 +71,7 @@ IndexedDBKey& IndexedDBKey::operator=(const IndexedDBKey& other) = default; bool IndexedDBKey::IsValid() const { - if (type_ == mojom::IDBKeyType::Invalid || type_ == mojom::IDBKeyType::Null) + if (type_ == mojom::IDBKeyType::Invalid || type_ == mojom::IDBKeyType::None) return false; if (type_ == blink::mojom::IDBKeyType::Array) { @@ -114,7 +114,7 @@ case mojom::IDBKeyType::Number: return Compare(number_, other.number_); case mojom::IDBKeyType::Invalid: - case mojom::IDBKeyType::Null: + case mojom::IDBKeyType::None: case mojom::IDBKeyType::Min: default: NOTREACHED();
diff --git a/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc b/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc index 50a9685..17aec06 100644 --- a/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc +++ b/third_party/blink/common/indexeddb/indexeddb_key_unittest.cc
@@ -23,7 +23,7 @@ keys.push_back(IndexedDBKey()); estimates.push_back(16u); // Overhead. - keys.push_back(IndexedDBKey(mojom::IDBKeyType::Null)); + keys.push_back(IndexedDBKey(mojom::IDBKeyType::None)); estimates.push_back(16u); double number = 3.14159;
diff --git a/third_party/blink/perf_tests/xss_auditor/large-post-many-events.html b/third_party/blink/perf_tests/xss_auditor/large-post-many-events.html deleted file mode 100644 index c26181f..0000000 --- a/third_party/blink/perf_tests/xss_auditor/large-post-many-events.html +++ /dev/null
@@ -1,51 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> -<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1"> -<title>WebKit test - use for detect speed differences when submitting the form</title> -<style type="text/css"> -BODY { background-color: #F0F0F0 } - -BODY, TABLE, TD { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 12px; -} -.funcDesc { background-color:#9F8E1C; color:#000000; /* background-color:#ffffbb; */ } -.t { font-family:courier; } -.tro { font-family:courier; background-color: #EBEBE4; } -.ro { background-color: #EBEBE4; } -#tableHeaders th { background-color:#F0F0F0; } -#tableRowstd { background-color:#F0F0F0; } -</style> -<script> -window.onload = function() { - document.getElementById("score").textContent = window.performance.timing.domContentLoadedEventStart - window.performance.timing.responseStart; -} -</script> -</head> -<body> - -<form id="frmName" name="frmName" method="post" action="large-post-many-events.html"> - -<div style="margin:0 auto; width:600px; background-color:#bbb; padding:20px;"> -Score (smaller is better): <span id="score">Running...</span> -</div> - -<input type="submit" value="Request Page Again"> -<br><br> - - -<div id="divMainTable" style="padding:0; border:0; overflow:auto; height:450px;"> -<table id="tableRows" border="0" cellpadding="3" cellspacing="1" style="background-color:black; width:;"> - - -<script> -for (var i=0; i < 400; ++i) { - document.write("<tr><td><a href=\"changed-name.php?ID=" + i + "\" target=\"_blank\">ChangedName, ChangedName</a></td> <td width=\"80px\">22331133</td> <td>06.02.2010</td> <td ondblclick=\"tR('" + i + "_1865_5721','')\"> 22:15 </td> <td><input type=\"text\" name=\"frmI1_" + i + "_1865_5721\" onblur=\"chkT(this);\" size=\"5\" class=\"t\" value=\"00:00\"></td> <td><input type=\"text\" name=\"frmU1_" + i + "_1865_5721\" onblur=\"chkT(this);\" size=\"5\" class=\"t\" value=\"00:00\"></td> <td><input type=\"text\" name=\"frmI2_" + i + "_1865_5721\" onblur=\"chkT(this);\" size=\"5\" class=\"t\" value=\"00:00\"></td> <td><input type=\"text\" name=\"frmU2_" + i + "_1865_5721\" onblur=\"chkT(this);\" size=\"5\" class=\"t\" value=\"00:00\"></td> <td><input type=\"text\" name=\"frmLU_" + i + "_1865_5721\" onblur=\"chkT(this);\" size=\"5\" class=\"t\" value=\"00:00\"></td> <td> <select name=\"frmOK_" + i + "_1865_5721\" onblur=\"checkFlag(this)\" onchange=\"tOK(this)\" > <option value=\"0\" selected=\"selected\">Nei</option> <option value=\"1\">Ja</option></td> </select> <td><a href=\"changed-another-name.php?ID=1865\">Changed name</a></td> <td>Changed name</td> <td> BLS </td> <td align=\"center\"> 201 </td> <td><div style=\"display:none;\"><input type=\"checkbox\" id=\"funcFlag_" + i + "_1865_5721\" value=\"\" name=\"funcFlag[]\"></div> <select name=\"frmUarr_" + i + "_1865_5721\" onchange=\"chkVFunc(this)\" style=\"background-color:#FFFFFF;\"> <option value=\"5719\" style=\"background-color:#FFFFFF;\">Changed1 (22:15 - 05:00)</option> <option value=\"5720\" style=\"background-color:#FFFFFF;\">Changed2 (22:15 - 05:00)</option> <option value=\"5721\" selected=\"selected\" style=\"background-color:#FFFFFF;\">Changed3 (22:15 - 05:00)</option> <option value=\"5787\" style=\"background-color:#FF8800\">Changed4 (22:15 - 22:30)</option> <option class=\"funcDesc\" value=\"0\" disabled=\"disabled\"> Changed text here as well</option> <option class=\"funcDesc\" value=\"0\" disabled=\"disabled\"> Changed text here also</option> </select><input type=\"hidden\" id=\"frmUarr_" + i + "_1865_5721_h\" value=\"5721\"></td> <td align=\"center\" > <select name=\"frmJobb_" + i + "_1865_5721\" title=\"JA\" onchange=\"checkFlag(this)\"> <option value=\"1\">Chan</option> <option value=\"2\" disabled=\"disabled\">Chan</option> <option value=\"3\" selected=\"selected\">Chan</option> </select></td> <td><input class=\"ro\" type=\"text\" readonly=\"readonly\" onblur=\"checkFlag(this)\" name=\"frmKommArb_" + i + "_1865_5721\" value=\"\" size=\"20\"></td> <td><input class=\"ro\" type=\"text\" readonly=\"readonly\" onblur=\"checkFlag(this)\" name=\"frmKommKru_" + i + "_1865_5721\" value=\"\" size=\"20\"></td> <td><input type=\"text\" onblur=\"checkFlag(this)\" name=\"frmKomm_" + i + "_1865_5721\" value=\"\" size=\"20\"></td> <td align=\"center\" style=\"\"><input type=\"checkbox\" onclick=\"checkUncheckOpptatt(this,this.value)\" id=\"O_" + i + "_1\" name=\"frmAnsOppt[]\" value=\"" + i + "_2010-02-06\" style=\"margin-left:20px; margin-right:20px;\"></td> </tr>"); -} -</script> -</table> -</form> -</div> -</body> -</html>
diff --git a/third_party/blink/perf_tests/xss_auditor/large-post-many-inline-scripts-and-events.html b/third_party/blink/perf_tests/xss_auditor/large-post-many-inline-scripts-and-events.html deleted file mode 100644 index 9eaa93f..0000000 --- a/third_party/blink/perf_tests/xss_auditor/large-post-many-inline-scripts-and-events.html +++ /dev/null
@@ -1,10 +0,0 @@ -<form action="resources/target-for-large-post-many-inline-scripts-and-events.html" method=POST> -<input name="a" type="hidden"> -<input type=submit> -</form> -<script> -var val = ""; -for (i = 0; i < 200000; ++i) - val += Math.random(); -document.getElementsByName("a")[0].value = val; -</script>
diff --git a/third_party/blink/perf_tests/xss_auditor/resources/target-for-large-post-many-inline-scripts-and-events.html b/third_party/blink/perf_tests/xss_auditor/resources/target-for-large-post-many-inline-scripts-and-events.html deleted file mode 100644 index 37ada235..0000000 --- a/third_party/blink/perf_tests/xss_auditor/resources/target-for-large-post-many-inline-scripts-and-events.html +++ /dev/null
@@ -1,1287 +0,0 @@ -<script> -window.onload = function() { - document.getElementById("score").textContent = window.performance.timing.domContentLoadedEventStart - window.performance.timing.responseStart; -} -</script> -Score (smaller is better): <span id="score"></span><br> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<a href="javascript:return '0'"></a> -.<img onclick="alert('0')"> -<script src="data:text/plain,'%30'"></script> -<script>\x30</script> -<br>Done.
diff --git a/third_party/blink/public/common/indexeddb/indexed_db_default_mojom_traits.h b/third_party/blink/public/common/indexeddb/indexed_db_default_mojom_traits.h index bc83906..35ad7e1 100644 --- a/third_party/blink/public/common/indexeddb/indexed_db_default_mojom_traits.h +++ b/third_party/blink/public/common/indexeddb/indexed_db_default_mojom_traits.h
@@ -103,8 +103,8 @@ static bool other_invalid(const blink::IndexedDBKey& key) { return key.type() == blink::mojom::IDBKeyType::Invalid; } - static bool other_null(const blink::IndexedDBKey& key) { - return key.type() == blink::mojom::IDBKeyType::Null; + static bool other_none(const blink::IndexedDBKey& key) { + return key.type() == blink::mojom::IDBKeyType::None; } };
diff --git a/third_party/blink/public/common/indexeddb/indexeddb_key_range.h b/third_party/blink/public/common/indexeddb/indexeddb_key_range.h index 0756d6c..cf284b2 100644 --- a/third_party/blink/public/common/indexeddb/indexeddb_key_range.h +++ b/third_party/blink/public/common/indexeddb/indexeddb_key_range.h
@@ -31,8 +31,8 @@ bool IsEmpty() const; private: - blink::IndexedDBKey lower_ = blink::IndexedDBKey(mojom::IDBKeyType::Null); - blink::IndexedDBKey upper_ = blink::IndexedDBKey(mojom::IDBKeyType::Null); + blink::IndexedDBKey lower_ = blink::IndexedDBKey(mojom::IDBKeyType::None); + blink::IndexedDBKey upper_ = blink::IndexedDBKey(mojom::IDBKeyType::None); bool lower_open_ = false; bool upper_open_ = false; };
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index 286d9381..8d4161ac 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -47,12 +47,13 @@ Date, Number, - // Null is used to represent the lack of a key, e.g. when a key range + // None is used to represent the lack of a key, e.g. when a key range // has no upper/lower bound. - Null, + // TODO(jsbell): Consider using Optional<> instead. + None, // Min is used to encode the lower bound of a construct in leveldb, e.g. - // all entries in a store are from [{id, min}, {id+1, min}). It should + // all entries in a store are in [{id, min}, {id+1, min}). It should // only appear in browser code. Min, }; @@ -63,10 +64,8 @@ mojo_base.mojom.String16 string; double date; double number; - // TODO(jsbell): These types should be cleaned up end-to-end, leaving only the - // dataful options above. - bool other_invalid; - bool other_null; + // TODO(jsbell): Consider using Optional<> instead. + bool other_none; }; // Defined as a structure so that it can by typemapped with StructTraits.
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h index cfe5f74..51beb6d 100644 --- a/third_party/blink/public/web/web_settings.h +++ b/third_party/blink/public/web/web_settings.h
@@ -275,7 +275,6 @@ virtual void SetWebGLErrorsToConsoleEnabled(bool) = 0; virtual void SetWebSecurityEnabled(bool) = 0; virtual void SetWideViewportQuirkEnabled(bool) = 0; - virtual void SetXSSAuditorEnabled(bool) = 0; virtual void SetMediaControlsEnabled(bool) = 0; virtual void SetDoNotUpdateSelectionOnMutatingSelectionRange(bool) = 0; virtual void SetLowPriorityIframesThreshold(WebEffectiveConnectionType) = 0;
diff --git a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc index bbd2c2f..ff1a21a 100644 --- a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
@@ -95,7 +95,7 @@ case mojom::IDBKeyType::Min: NOTREACHED(); return v8::Local<v8::Value>(); - case mojom::IDBKeyType::Null: + case mojom::IDBKeyType::None: return v8::Null(isolate); case mojom::IDBKeyType::Number: return v8::Number::New(isolate, key->Number());
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 5a870d06..c6a9d3a 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -304,7 +304,7 @@ // Some of these elements are handled with other adjustments above. if (IsA<HTMLBRElement>(element) || IsHTMLWBRElement(element) || IsHTMLMeterElement(element) || IsHTMLProgressElement(element) || - IsHTMLCanvasElement(element) || IsHTMLMediaElement(element) || + IsA<HTMLCanvasElement>(element) || IsHTMLMediaElement(element) || IsHTMLInputElement(element) || IsHTMLTextAreaElement(element) || IsHTMLSelectElement(element)) { style.SetDisplay(EDisplay::kNone); @@ -446,7 +446,7 @@ TouchAction inherited_action = parent_style.GetEffectiveTouchAction(); bool is_replaced_canvas = - element && IsHTMLCanvasElement(element) && + element && IsA<HTMLCanvasElement>(element) && element->GetDocument().GetFrame() && element->GetDocument().CanExecuteScripts(kNotAboutToExecuteScript); bool is_non_replaced_inline_elements =
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 0240e3e..b6d4e4d4 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -7217,7 +7217,7 @@ HTMLDialogElement* Document::ActiveModalDialog() const { for (auto it = top_layer_elements_.rbegin(); it != top_layer_elements_.rend(); ++it) { - if (auto* dialog = ToHTMLDialogElementOrNull(*it->Get())) + if (auto* dialog = DynamicTo<HTMLDialogElement>(*it->Get())) return dialog; }
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc index d41cee01..8aef31c 100644 --- a/third_party/blink/renderer/core/editing/editing_utilities.cc +++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -1690,7 +1690,7 @@ return nullptr; if (layout_object->IsCanvas()) { - return ToHTMLCanvasElement(const_cast<Node&>(node)) + return To<HTMLCanvasElement>(const_cast<Node&>(node)) .Snapshot(kFrontBuffer, kPreferNoAcceleration); } @@ -1712,7 +1712,7 @@ if (IsSVGImageElement(node)) return To<SVGElement>(node).ImageSourceURL(); if (IsHTMLEmbedElement(node) || IsHTMLObjectElement(node) || - IsHTMLCanvasElement(node)) + IsA<HTMLCanvasElement>(node)) return To<HTMLElement>(node).ImageSourceURL(); return AtomicString(); }
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc index 962530bb..fea6b695 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.cc +++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -335,10 +335,6 @@ settings_->SetJavaScriptCanAccessClipboard(enabled); } -void WebSettingsImpl::SetXSSAuditorEnabled(bool enabled) { - settings_->SetXSSAuditorEnabled(enabled); -} - void WebSettingsImpl::SetTextTrackKindUserPreference( TextTrackKindUserPreference preference) { settings_->SetTextTrackKindUserPreference(
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h index 3f1b4cec..6bb7eab 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.h +++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -196,7 +196,6 @@ void SetWebGLErrorsToConsoleEnabled(bool) override; void SetWebSecurityEnabled(bool) override; void SetWideViewportQuirkEnabled(bool) override; - void SetXSSAuditorEnabled(bool) override; void SetMediaControlsEnabled(bool) override; void SetDoNotUpdateSelectionOnMutatingSelectionRange(bool) override; void SetLowPriorityIframesThreshold(WebEffectiveConnectionType) override;
diff --git a/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc b/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc index 3725c34..7d58873 100644 --- a/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc +++ b/third_party/blink/renderer/core/frame/csp/execution_context_csp_delegate.cc
@@ -200,8 +200,7 @@ // inconsistent. : document->CompleteURLWithOverride( report_endpoint, document->FallbackBaseURL()); - PingLoader::SendViolationReport( - frame, url, report, PingLoader::kContentSecurityPolicyViolationReport); + PingLoader::SendViolationReport(frame, url, report); } }
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index 72d9508..5f113450 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -172,11 +172,6 @@ }, { - name: "xssAuditorEnabled", - initial: false, - }, - - { name: "preferCompositingToLCDTextEnabled", initial: false, invalidate: "AcceleratedCompositing",
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index fc42401f3..fcbb75f 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2303,7 +2303,7 @@ void WebLocalFrameImpl::CopyImageAt(const WebPoint& pos_in_viewport) { HitTestResult result = HitTestResultForVisualViewportPos(pos_in_viewport); - if (!IsHTMLCanvasElement(result.InnerNodeOrImageMapImage()) && + if (!IsA<HTMLCanvasElement>(result.InnerNodeOrImageMapImage()) && result.AbsoluteImageURL().IsEmpty()) { // There isn't actually an image at these coordinates. Might be because // the window scrolled while the context menu was open or because the page @@ -2325,7 +2325,7 @@ void WebLocalFrameImpl::SaveImageAt(const WebPoint& pos_in_viewport) { Node* node = HitTestResultForVisualViewportPos(pos_in_viewport) .InnerNodeOrImageMapImage(); - if (!node || !(IsHTMLCanvasElement(*node) || IsHTMLImageElement(*node))) + if (!node || !(IsA<HTMLCanvasElement>(*node) || IsHTMLImageElement(*node))) return; String url = To<Element>(*node).ImageSourceURL();
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.cc b/third_party/blink/renderer/core/fullscreen/fullscreen.cc index 5cb19194..047102b 100644 --- a/third_party/blink/renderer/core/fullscreen/fullscreen.cc +++ b/third_party/blink/renderer/core/fullscreen/fullscreen.cc
@@ -286,7 +286,7 @@ return false; // |pending| is not a dialog element. - if (IsHTMLDialogElement(pending)) + if (IsA<HTMLDialogElement>(pending)) return false; // The fullscreen element ready check for |pending| returns false.
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc b/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc index 1cd5df9..0ddd7b0 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc
@@ -45,7 +45,7 @@ GetDocument().documentElement()->SetInnerHTMLFromString( "<body><canvas id='c'></canvas></body>"); UpdateAllLifecyclePhasesForTest(); - canvas_element_ = ToHTMLCanvasElement(GetDocument().getElementById("c")); + canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c")); String canvas_type("2d"); CanvasContextCreationAttributesCore attributes; attributes.alpha = true;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc index 340695d..1c89d714 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -377,7 +377,7 @@ void HTMLFormElement::SubmitDialog(FormSubmission* form_submission) { for (Node* node = this; node; node = node->ParentOrShadowHostNode()) { - if (auto* dialog = ToHTMLDialogElementOrNull(*node)) { + if (auto* dialog = DynamicTo<HTMLDialogElement>(*node)) { dialog->close(form_submission->Result()); return; }
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.cc b/third_party/blink/renderer/core/html/html_dialog_element.cc index e1697bd..180fcd3 100644 --- a/third_party/blink/renderer/core/html/html_dialog_element.cc +++ b/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -50,7 +50,7 @@ // currently specified. This may change at any time. // See crbug/383230 and https://github.com/whatwg/html/issues/2393 . for (Node* node = FlatTreeTraversal::FirstChild(*dialog); node; node = next) { - next = IsHTMLDialogElement(*node) + next = IsA<HTMLDialogElement>(*node) ? FlatTreeTraversal::NextSkippingChildren(*node, dialog) : FlatTreeTraversal::Next(*node, dialog);
diff --git a/third_party/blink/renderer/core/html/parser/html_token.h b/third_party/blink/renderer/core/html/parser/html_token.h index 3176a0d..49fa9fb1 100644 --- a/third_party/blink/renderer/core/html/parser/html_token.h +++ b/third_party/blink/renderer/core/html/parser/html_token.h
@@ -378,12 +378,6 @@ return nullptr; } - // Used by the XSSAuditor to nuke XSS-laden attributes. - void EraseValueOfAttribute(wtf_size_t i) { - DCHECK(type_ == kStartTag || type_ == kEndTag); - attributes_[i].ClearValue(); - } - /* Character Tokens */ // Starting a character token works slightly differently than starting @@ -433,13 +427,6 @@ or_all_data_ |= character; } - // Only for XSSAuditor - void EraseCharacters() { - DCHECK_EQ(type_, kCharacter); - data_.clear(); - or_all_data_ = 0; - } - private: TokenType type_; Attribute::Range range_; // Always starts at zero.
diff --git a/third_party/blink/renderer/core/input/event_handler_test.cc b/third_party/blink/renderer/core/input/event_handler_test.cc index c468f46..1ce9059 100644 --- a/third_party/blink/renderer/core/input/event_handler_test.cc +++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -1019,8 +1019,7 @@ "<canvas style='width: 100px; height: 100px' id='first' " "onpointermove='return;'>"); - HTMLCanvasElement& canvas = - ToHTMLCanvasElement(*GetDocument().getElementById("first")); + auto& canvas = To<HTMLCanvasElement>(*GetDocument().getElementById("first")); ASSERT_FALSE(chrome_client_->ReceivedRequestForUnbufferedInput());
diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index 1ccbd3b9..1528667 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc
@@ -188,9 +188,9 @@ return WebInputEventResult::kNotHandled; if (event_type == event_type_names::kPointerdown) { - Node* node = target->ToNode(); - if (node && IsHTMLCanvasElement(*node) && - ToHTMLCanvasElement(*node).NeedsUnbufferedInputEvents()) { + auto* html_canvas_element = DynamicTo<HTMLCanvasElement>(target->ToNode()); + if (html_canvas_element && + html_canvas_element->NeedsUnbufferedInputEvents()) { frame_->GetChromeClient().RequestUnbufferedInputEvents(frame_); } }
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc index 4a27f2e..bd9e931 100644 --- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -262,7 +262,7 @@ if (!layout_object) continue; - if (IsHTMLCanvasElement(element) || IsHTMLEmbedElement(element) || + if (IsA<HTMLCanvasElement>(element) || IsHTMLEmbedElement(element) || IsHTMLImageElement(element) || IsHTMLObjectElement(element) || IsHTMLPictureElement(element) || element->IsSVGElement() || IsHTMLVideoElement(element)) {
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc index 78aa529..233682d 100644 --- a/third_party/blink/renderer/core/layout/layout_block_flow.cc +++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -537,7 +537,7 @@ UpdateAfterLayout(); - if (IsHTMLDialogElement(GetNode()) && IsOutOfFlowPositioned()) + if (IsA<HTMLDialogElement>(GetNode()) && IsOutOfFlowPositioned()) PositionDialog(); ClearNeedsLayout();
diff --git a/third_party/blink/renderer/core/layout/layout_html_canvas.cc b/third_party/blink/renderer/core/layout/layout_html_canvas.cc index 2847ccf..bf09cf44 100644 --- a/third_party/blink/renderer/core/layout/layout_html_canvas.cc +++ b/third_party/blink/renderer/core/layout/layout_html_canvas.cc
@@ -49,7 +49,7 @@ } void LayoutHTMLCanvas::CanvasSizeChanged() { - IntSize canvas_size = ToHTMLCanvasElement(GetNode())->Size(); + IntSize canvas_size = To<HTMLCanvasElement>(GetNode())->Size(); LayoutSize zoomed_size(canvas_size.Width() * StyleRef().EffectiveZoom(), canvas_size.Height() * StyleRef().EffectiveZoom()); @@ -82,7 +82,7 @@ void LayoutHTMLCanvas::InvalidatePaint( const PaintInvalidatorContext& context) const { - auto* element = ToHTMLCanvasElement(GetNode()); + auto* element = To<HTMLCanvasElement>(GetNode()); if (element->IsDirty()) element->DoDeferredPaintInvalidation(); @@ -90,7 +90,7 @@ } CompositingReasons LayoutHTMLCanvas::AdditionalCompositingReasons() const { - if (ToHTMLCanvasElement(GetNode())->ShouldBeDirectComposited()) + if (To<HTMLCanvasElement>(GetNode())->ShouldBeDirectComposited()) return CompositingReason::kCanvas; return CompositingReason::kNone; } @@ -98,7 +98,7 @@ void LayoutHTMLCanvas::StyleDidChange(StyleDifference diff, const ComputedStyle* old_style) { LayoutReplaced::StyleDidChange(diff, old_style); - ToHTMLCanvasElement(GetNode())->StyleDidChange(old_style, StyleRef()); + To<HTMLCanvasElement>(GetNode())->StyleDidChange(old_style, StyleRef()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc index 50493e5..0ee7f7b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -284,13 +284,13 @@ base::Optional<LayoutUnit> ComputeAbsoluteDialogYPosition( const LayoutObject& dialog, LayoutUnit height) { - if (!IsHTMLDialogElement(dialog.GetNode())) + auto* dialog_node = DynamicTo<HTMLDialogElement>(dialog.GetNode()); + if (!dialog_node) return base::nullopt; // This code implements <dialog> static-position spec. // // https://html.spec.whatwg.org/C/#the-dialog-element - HTMLDialogElement* dialog_node = ToHTMLDialogElement(dialog.GetNode()); if (dialog_node->GetCenteringMode() == HTMLDialogElement::kNotCentered) return base::nullopt;
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc index 4c1cd9a..b259e246 100644 --- a/third_party/blink/renderer/core/loader/ping_loader.cc +++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -241,18 +241,10 @@ void PingLoader::SendViolationReport(LocalFrame* frame, const KURL& report_url, - scoped_refptr<EncodedFormData> report, - ViolationReportType type) { + scoped_refptr<EncodedFormData> report) { ResourceRequest request(report_url); request.SetHttpMethod(http_names::kPOST); - switch (type) { - case kContentSecurityPolicyViolationReport: - request.SetHTTPContentType("application/csp-report"); - break; - case kXSSAuditorViolationReport: - request.SetHTTPContentType("application/xss-auditor-report"); - break; - } + request.SetHTTPContentType("application/csp-report"); request.SetKeepalive(true); request.SetHttpBody(std::move(report)); request.SetCredentialsMode(network::mojom::CredentialsMode::kSameOrigin);
diff --git a/third_party/blink/renderer/core/loader/ping_loader.h b/third_party/blink/renderer/core/loader/ping_loader.h index 50ed1c3..b76c4818 100644 --- a/third_party/blink/renderer/core/loader/ping_loader.h +++ b/third_party/blink/renderer/core/loader/ping_loader.h
@@ -62,18 +62,12 @@ STATIC_ONLY(PingLoader); public: - enum ViolationReportType { - kContentSecurityPolicyViolationReport, - kXSSAuditorViolationReport - }; - static void SendLinkAuditPing(LocalFrame*, const KURL& ping_url, const KURL& destination_url); static void SendViolationReport(LocalFrame*, const KURL& report_url, - scoped_refptr<EncodedFormData> report, - ViolationReportType); + scoped_refptr<EncodedFormData> report); // The last argument is guaranteed to be set to the size of payload if // these method return true. If these method returns false, the value
diff --git a/third_party/blink/renderer/core/loader/ping_loader_test.cc b/third_party/blink/renderer/core/loader/ping_loader_test.cc index 5ff8a3d2..f519b4d 100644 --- a/third_party/blink/renderer/core/loader/ping_loader_test.cc +++ b/third_party/blink/renderer/core/loader/ping_loader_test.cc
@@ -127,8 +127,7 @@ url_test_helpers::RegisterMockedURLLoad( ping_url, test::CoreTestDataPath("bar.html"), "text/html"); PingLoader::SendViolationReport(&GetFrame(), ping_url, - EncodedFormData::Create(), - PingLoader::kXSSAuditorViolationReport); + EncodedFormData::Create()); Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); const ResourceRequest& request = client_->PingRequest(); ASSERT_FALSE(request.IsNull());
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index 7424cfb..bc50b0e 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -245,7 +245,7 @@ data.alt_text = html_element->AltText(); } - if (IsHTMLCanvasElement(result.InnerNode())) { + if (IsA<HTMLCanvasElement>(result.InnerNode())) { data.media_type = WebContextMenuData::kMediaTypeCanvas; data.has_image_contents = true; } else if (!result.AbsoluteImageURL().IsEmpty()) {
diff --git a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc index 6ba5f94..0def054 100644 --- a/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc +++ b/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -102,7 +102,7 @@ static inline bool IsTextureLayerCanvas(const LayoutObject& layout_object) { if (layout_object.IsCanvas()) { - HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode()); + auto* canvas = To<HTMLCanvasElement>(layout_object.GetNode()); if (canvas->SurfaceLayerBridge()) return false; if (CanvasRenderingContext* context = canvas->RenderingContext()) @@ -113,7 +113,7 @@ static inline bool IsSurfaceLayerCanvas(const LayoutObject& layout_object) { if (layout_object.IsCanvas()) { - HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode()); + auto* canvas = To<HTMLCanvasElement>(layout_object.GetNode()); return canvas->SurfaceLayerBridge(); } return false; @@ -121,7 +121,7 @@ static inline bool IsCompositedCanvas(const LayoutObject& layout_object) { if (layout_object.IsCanvas()) { - HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode()); + auto* canvas = To<HTMLCanvasElement>(layout_object.GetNode()); if (canvas->SurfaceLayerBridge()) return true; if (CanvasRenderingContext* context = canvas->RenderingContext()) @@ -448,7 +448,7 @@ bool should_check_children = !foreground_layer_.get(); if (IsTextureLayerCanvas(GetLayoutObject())) { CanvasRenderingContext* context = - ToHTMLCanvasElement(GetLayoutObject().GetNode())->RenderingContext(); + To<HTMLCanvasElement>(GetLayoutObject().GetNode())->RenderingContext(); cc::Layer* layer = context ? context->CcLayer() : nullptr; // Determine whether the external texture layer covers the whole graphics // layer. This may not be the case if there are box decorations or @@ -875,7 +875,7 @@ /*prevent_contents_opaque_changes=*/true); } else if (layout_object.IsCanvas()) { graphics_layer_->SetContentsToCcLayer( - ToHTMLCanvasElement(layout_object.GetNode())->ContentsCcLayer(), + To<HTMLCanvasElement>(layout_object.GetNode())->ContentsCcLayer(), /*prevent_contents_opaque_changes=*/false); layer_config_changed = true; } @@ -1954,7 +1954,7 @@ if (has_painted_content && IsTextureLayerCanvas(GetLayoutObject())) { CanvasRenderingContext* context = - ToHTMLCanvasElement(GetLayoutObject().GetNode())->RenderingContext(); + To<HTMLCanvasElement>(GetLayoutObject().GetNode())->RenderingContext(); // Content layer may be null if context is lost. if (cc::Layer* content_layer = context->CcLayer()) { Color bg_color(Color::kTransparent);
diff --git a/third_party/blink/renderer/core/paint/html_canvas_painter.cc b/third_party/blink/renderer/core/paint/html_canvas_painter.cc index 0d911dc2..05c8f34a 100644 --- a/third_party/blink/renderer/core/paint/html_canvas_painter.cc +++ b/third_party/blink/renderer/core/paint/html_canvas_painter.cc
@@ -36,8 +36,7 @@ PhysicalRect paint_rect = layout_html_canvas_.ReplacedContentRect(); paint_rect.Move(paint_offset); - HTMLCanvasElement* canvas = - ToHTMLCanvasElement(layout_html_canvas_.GetNode()); + auto* canvas = To<HTMLCanvasElement>(layout_html_canvas_.GetNode()); if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { if (auto* layer = canvas->ContentsCcLayer()) {
diff --git a/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc b/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc index 3cdbd06c..b2f2f20 100644 --- a/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc +++ b/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
@@ -78,8 +78,7 @@ // Not using SetBodyInnerHTML() because we need to test before document // lifecyle update. GetDocument().body()->SetInnerHTMLFromString("<canvas width=300 height=200>"); - HTMLCanvasElement* element = - ToHTMLCanvasElement(GetDocument().body()->firstChild()); + auto* element = To<HTMLCanvasElement>(GetDocument().body()->firstChild()); CanvasContextCreationAttributesCore attributes; attributes.alpha = true; CanvasRenderingContext* context =
diff --git a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index 6eb704a..8e8a7fc 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc
@@ -207,7 +207,7 @@ return ax::mojom::Role::kImage; } - if (IsHTMLCanvasElement(node)) + if (IsA<HTMLCanvasElement>(node)) return ax::mojom::Role::kCanvas; if (css_box && css_box->IsLayoutView())
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 5658e0c9..467b6ffc 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -652,7 +652,7 @@ if (GetNode()->HasTagName(kAddressTag)) return ax::mojom::Role::kGenericContainer; - if (IsHTMLDialogElement(*GetNode())) + if (IsA<HTMLDialogElement>(*GetNode())) return ax::mojom::Role::kDialog; // The HTML element should not be exposed as an element. That's what the @@ -1246,7 +1246,7 @@ if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal)) return modal; - if (GetNode() && IsHTMLDialogElement(*GetNode())) + if (GetNode() && IsA<HTMLDialogElement>(*GetNode())) return To<Element>(GetNode())->IsInTopLayer(); return false; @@ -1267,7 +1267,7 @@ if (IsDetached()) return false; Node* node = this->GetNode(); - return IsHTMLCanvasElement(node) && node->hasChildren(); + return IsA<HTMLCanvasElement>(node) && node->hasChildren(); } int AXNodeObject::HeadingLevel() const {
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc index 2986a4d..9e7f31e 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc
@@ -64,7 +64,7 @@ GetDocument().documentElement()->SetInnerHTMLFromString( "<body><canvas id='c'></canvas></body>"); UpdateAllLifecyclePhasesForTest(); - canvas_element_ = ToHTMLCanvasElement(GetDocument().getElementById("c")); + canvas_element_ = To<HTMLCanvasElement>(GetDocument().getElementById("c")); } TEST_F(CanvasRenderingContext2DAPITest, SetShadowColor_Clamping) { @@ -310,8 +310,7 @@ padding:10px; margin:5px;'> <button id='button'></button></canvas> )HTML"); - HTMLCanvasElement* canvas = - ToHTMLCanvasElement(document.getElementById("canvas")); + auto* canvas = To<HTMLCanvasElement>(document.getElementById("canvas")); String canvas_type("2d"); CanvasContextCreationAttributesCore attributes; @@ -327,8 +326,7 @@ AXContext ax_context(GetDocument()); Element* button_element = GetDocument().getElementById("button"); - HTMLCanvasElement* canvas = - ToHTMLCanvasElement(GetDocument().getElementById("canvas")); + auto* canvas = To<HTMLCanvasElement>(GetDocument().getElementById("canvas")); CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(canvas->RenderingContext()); @@ -357,8 +355,7 @@ AXContext ax_context(GetDocument()); Element* button_element = GetDocument().getElementById("button"); - HTMLCanvasElement* canvas = - ToHTMLCanvasElement(GetDocument().getElementById("canvas")); + auto* canvas = To<HTMLCanvasElement>(GetDocument().getElementById("canvas")); CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(canvas->RenderingContext());
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 2f1d4ae6..b2d723c 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -208,7 +208,7 @@ SetHtmlInnerHTML( "<body><canvas id='c'></canvas><canvas id='d'></canvas></body>"); - canvas_element_ = ToHTMLCanvasElement(GetElementById("c")); + canvas_element_ = To<HTMLCanvasElement>(GetElementById("c")); full_image_data_ = ImageData::Create(IntSize(10, 10)); partial_image_data_ = ImageData::Create(IntSize(2, 2)); @@ -548,7 +548,7 @@ } TEST_F(CanvasRenderingContext2DTest, ImageResourceLifetime) { - auto* canvas = ToHTMLCanvasElement( + auto* canvas = To<HTMLCanvasElement>( GetDocument().CreateRawElement(html_names::kCanvasTag)); canvas->SetSize(IntSize(40, 40)); ImageBitmap* image_bitmap_derived = nullptr; @@ -610,8 +610,8 @@ EXPECT_EQ(1u, GetGlobalAcceleratedContextCount()); // Creating a different accelerated image buffer - HTMLCanvasElement* anotherCanvas = - ToHTMLCanvasElement(GetDocument().getElementById("d")); + auto* anotherCanvas = + To<HTMLCanvasElement>(GetDocument().getElementById("d")); CanvasContextCreationAttributesCore attributes; anotherCanvas->GetCanvasRenderingContext("2d", attributes); IntSize size2(10, 5);
diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc index f6f9d78..64ad351e 100644 --- a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc +++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
@@ -51,7 +51,7 @@ void SetUp() override { PageTestBase::SetUp(); SetHtmlInnerHTML("<body><canvas id='c'></canvas></body>"); - canvas_element_ = ToHTMLCanvasElement(GetElementById("c")); + canvas_element_ = To<HTMLCanvasElement>(GetElementById("c")); } HTMLCanvasElement& canvas_element() const { return *canvas_element_; }
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc b/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc index f2cb656..e1c9e9ae 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc
@@ -71,7 +71,7 @@ WTF::BindRepeating(factory, WTF::Unretained(&gl_))); PageTestBase::SetUp(); SetHtmlInnerHTML("<body><canvas id='c'></canvas></body>"); - HTMLCanvasElement* canvas_element = ToHTMLCanvasElement(GetElementById("c")); + auto* canvas_element = To<HTMLCanvasElement>(GetElementById("c")); DummyExceptionStateForTesting exception_state; offscreen_canvas_ = HTMLCanvasElementModule::transferControlToOffscreen(
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc index c63514a..b32cc37 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -269,9 +269,9 @@ const IDBKey* current_primary_key = IdbPrimaryKey(); if (!key) - key = IDBKey::CreateNull(); + key = IDBKey::CreateNone(); - if (key->GetType() != mojom::IDBKeyType::Null) { + if (key->GetType() != mojom::IDBKeyType::None) { DCHECK(key_); if (direction_ == mojom::IDBCursorDirection::Next || direction_ == mojom::IDBCursorDirection::NextNoDuplicate) { @@ -299,7 +299,7 @@ } if (!primary_key) - primary_key = IDBKey::CreateNull(); + primary_key = IDBKey::CreateNone(); // FIXME: We're not using the context from when continue was called, which // means the callback will be on the original context openCursor was called
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_key.cc b/third_party/blink/renderer/modules/indexeddb/idb_key.cc index 7ac9f4d..9a3ac0c0 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_key.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_key.cc
@@ -50,13 +50,13 @@ // static std::unique_ptr<IDBKey> IDBKey::Clone(const IDBKey* rkey) { if (!rkey) - return IDBKey::CreateNull(); + return IDBKey::CreateNone(); switch (rkey->GetType()) { case mojom::IDBKeyType::Invalid: return IDBKey::CreateInvalid(); - case mojom::IDBKeyType::Null: - return IDBKey::CreateNull(); + case mojom::IDBKeyType::None: + return IDBKey::CreateNone(); case mojom::IDBKeyType::Array: { IDBKey::KeyArray lkey_array; const auto& rkey_array = rkey->Array(); @@ -83,11 +83,11 @@ IDBKey::IDBKey() : type_(mojom::IDBKeyType::Invalid), size_estimate_(kIDBKeyOverheadSize) {} -// Must be Invalid or Null. +// Must be Invalid or None. IDBKey::IDBKey(mojom::IDBKeyType type) : type_(type), size_estimate_(kIDBKeyOverheadSize) { DCHECK(type_ == mojom::IDBKeyType::Invalid || - type_ == mojom::IDBKeyType::Null); + type_ == mojom::IDBKeyType::None); } // Must be Number or Date. @@ -168,7 +168,7 @@ // These values cannot be compared to each other. case mojom::IDBKeyType::Invalid: - case mojom::IDBKeyType::Null: + case mojom::IDBKeyType::None: case mojom::IDBKeyType::Min: NOTREACHED(); return 0;
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_key.h b/third_party/blink/renderer/modules/indexeddb/idb_key.h index 73dc8eba..02f0da3 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_key.h +++ b/third_party/blink/renderer/modules/indexeddb/idb_key.h
@@ -59,8 +59,8 @@ return base::WrapUnique(new IDBKey()); } - static std::unique_ptr<IDBKey> CreateNull() { - return base::WrapUnique(new IDBKey(mojom::IDBKeyType::Null)); + static std::unique_ptr<IDBKey> CreateNone() { + return base::WrapUnique(new IDBKey(mojom::IDBKeyType::None)); } static std::unique_ptr<IDBKey> CreateNumber(double number) {
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_value.h b/third_party/blink/renderer/modules/indexeddb/idb_value.h index e8f39091..8bf8eac 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_value.h +++ b/third_party/blink/renderer/modules/indexeddb/idb_value.h
@@ -51,8 +51,8 @@ // Injects a primary key into a value coming from the backend. void SetInjectedPrimaryKey(std::unique_ptr<IDBKey> primary_key, IDBKeyPath primary_key_path) { - // If the given key is type Null, ignore it. - if (primary_key && primary_key->GetType() == mojom::IDBKeyType::Null) + // If the given key is type None, ignore it. + if (primary_key && primary_key->GetType() == mojom::IDBKeyType::None) primary_key.reset(); primary_key_ = std::move(primary_key); key_path_ = std::move(primary_key_path);
diff --git a/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc b/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc index 60ba099..8196754 100644 --- a/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc +++ b/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc
@@ -84,8 +84,6 @@ GetTag(const std::unique_ptr<blink::IDBKey>& key) { DCHECK(key.get()); switch (key->GetType()) { - case blink::mojom::IDBKeyType::Invalid: - return blink::mojom::IDBKeyDataDataView::Tag::OTHER_INVALID; case blink::mojom::IDBKeyType::Array: return blink::mojom::IDBKeyDataDataView::Tag::KEY_ARRAY; case blink::mojom::IDBKeyType::Binary: @@ -96,14 +94,15 @@ return blink::mojom::IDBKeyDataDataView::Tag::DATE; case blink::mojom::IDBKeyType::Number: return blink::mojom::IDBKeyDataDataView::Tag::NUMBER; - case blink::mojom::IDBKeyType::Null: - return blink::mojom::IDBKeyDataDataView::Tag::OTHER_NULL; + case blink::mojom::IDBKeyType::None: + return blink::mojom::IDBKeyDataDataView::Tag::OTHER_NONE; // Not used, fall through to NOTREACHED. - case blink::mojom::IDBKeyType::Min:; + case blink::mojom::IDBKeyType::Invalid: // Only used in blink. + case blink::mojom::IDBKeyType::Min:; // Only used in the browser. } NOTREACHED(); - return blink::mojom::IDBKeyDataDataView::Tag::OTHER_INVALID; + return blink::mojom::IDBKeyDataDataView::Tag::OTHER_NONE; } // static @@ -139,11 +138,8 @@ case blink::mojom::IDBKeyDataDataView::Tag::NUMBER: *out = blink::IDBKey::CreateNumber(data.number()); return true; - case blink::mojom::IDBKeyDataDataView::Tag::OTHER_INVALID: - *out = blink::IDBKey::CreateInvalid(); - return true; - case blink::mojom::IDBKeyDataDataView::Tag::OTHER_NULL: - *out = blink::IDBKey::CreateNull(); + case blink::mojom::IDBKeyDataDataView::Tag::OTHER_NONE: + *out = blink::IDBKey::CreateNone(); return true; } @@ -361,8 +357,8 @@ blink::mojom::blink::IDBKeyRangePtr, const blink::IDBKeyRange*>::Convert(const blink::IDBKeyRange* input) { if (!input) { - std::unique_ptr<blink::IDBKey> lower = blink::IDBKey::CreateNull(); - std::unique_ptr<blink::IDBKey> upper = blink::IDBKey::CreateNull(); + std::unique_ptr<blink::IDBKey> lower = blink::IDBKey::CreateNone(); + std::unique_ptr<blink::IDBKey> upper = blink::IDBKey::CreateNone(); return blink::mojom::blink::IDBKeyRange::New( std::move(lower), std::move(upper), false /* lower_open */, false /* upper_open */); @@ -379,8 +375,8 @@ TypeConverter<blink::mojom::blink::IDBKeyRangePtr, blink::IDBKeyRange*>::Convert(blink::IDBKeyRange* input) { if (!input) { - std::unique_ptr<blink::IDBKey> lower = blink::IDBKey::CreateNull(); - std::unique_ptr<blink::IDBKey> upper = blink::IDBKey::CreateNull(); + std::unique_ptr<blink::IDBKey> lower = blink::IDBKey::CreateNone(); + std::unique_ptr<blink::IDBKey> upper = blink::IDBKey::CreateNone(); return blink::mojom::blink::IDBKeyRange::New( std::move(lower), std::move(upper), false /* lower_open */, false /* upper_open */);
diff --git a/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h b/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h index 44cd49e..5a94ff71 100644 --- a/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h +++ b/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h
@@ -110,8 +110,8 @@ static bool other_invalid(const std::unique_ptr<blink::IDBKey>& key) { return key->GetType() == blink::mojom::IDBKeyType::Invalid; } - static bool other_null(const std::unique_ptr<blink::IDBKey>& key) { - return key->GetType() == blink::mojom::IDBKeyType::Null; + static bool other_none(const std::unique_ptr<blink::IDBKey>& key) { + return key->GetType() == blink::mojom::IDBKeyType::None; } };
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc index d0848d2..0aec3ce 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc
@@ -100,8 +100,8 @@ DCHECK(key && primary_key); std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); - if (key->GetType() == mojom::IDBKeyType::Null && - primary_key->GetType() == mojom::IDBKeyType::Null) { + if (key->GetType() == mojom::IDBKeyType::None && + primary_key->GetType() == mojom::IDBKeyType::None) { // No key(s), so this would qualify for a prefetch. ++continue_count_;
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc index 478acf1..7b9a06c 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl_unittest.cc
@@ -109,7 +109,7 @@ class WebIDBCursorImplTest : public testing::Test { public: - WebIDBCursorImplTest() : null_key_(IDBKey::CreateNull()) { + WebIDBCursorImplTest() : null_key_(IDBKey::CreateNone()) { mojom::blink::IDBCursorAssociatedPtr ptr; mock_cursor_ = std::make_unique<MockCursorImpl>( mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr));
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index 3fe7946..8935fb37 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -129,8 +129,7 @@ : thread_(CurrentThread()), persistent_region_(std::make_unique<PersistentRegion>()), weak_persistent_region_(std::make_unique<PersistentRegion>()), - start_of_stack_(reinterpret_cast<intptr_t*>(WTF::GetStackStart())), - end_of_stack_(reinterpret_cast<intptr_t*>(WTF::GetStackStart())), + start_of_stack_(reinterpret_cast<Address*>(WTF::GetStackStart())), gc_state_(kNoGCScheduled), gc_phase_(GCPhase::kNone), reason_for_scheduled_gc_(BlinkGC::GCReason::kForcedGCForTesting), @@ -280,10 +279,10 @@ NO_SANITIZE_ADDRESS void ThreadState::VisitAsanFakeStackForPointer(MarkingVisitor* visitor, - Address ptr) { + Address ptr, + Address* start_of_stack, + Address* end_of_stack) { #if defined(ADDRESS_SANITIZER) - Address* start = reinterpret_cast<Address*>(start_of_stack_); - Address* end = reinterpret_cast<Address*>(end_of_stack_); Address* fake_frame_start = nullptr; Address* fake_frame_end = nullptr; Address* maybe_fake_frame = reinterpret_cast<Address*>(ptr); @@ -293,7 +292,8 @@ reinterpret_cast<void**>(&fake_frame_end))); if (real_frame_for_fake_frame) { // This is a fake frame from the asan fake stack. - if (real_frame_for_fake_frame > end && start > real_frame_for_fake_frame) { + if (real_frame_for_fake_frame > end_of_stack && + start_of_stack > real_frame_for_fake_frame) { // The real stack address for the asan fake frame is // within the stack range that we need to scan so we need // to visit the values in the fake frame. @@ -301,7 +301,7 @@ heap_->CheckAndMarkPointer(visitor, *p); } } -#endif +#endif // ADDRESS_SANITIZER } // Stack scanning may overrun the bounds of local objects and/or race with @@ -309,18 +309,15 @@ NO_SANITIZE_ADDRESS NO_SANITIZE_HWADDRESS NO_SANITIZE_THREAD -void ThreadState::VisitStack(MarkingVisitor* visitor) { +void ThreadState::VisitStack(MarkingVisitor* visitor, Address* end_of_stack) { DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack); - Address* start = reinterpret_cast<Address*>(start_of_stack_); - Address* end = reinterpret_cast<Address*>(end_of_stack_); - // Ensure that current is aligned by address size otherwise the loop below // will read past start address. Address* current = reinterpret_cast<Address*>( - reinterpret_cast<intptr_t>(end) & ~(sizeof(Address) - 1)); + reinterpret_cast<intptr_t>(end_of_stack) & ~(sizeof(Address) - 1)); - for (; current < start; ++current) { + for (; current < start_of_stack_; ++current) { Address ptr = *current; #if defined(MEMORY_SANITIZER) // |ptr| may be uninitialized by design. Mark it as initialized to keep @@ -331,7 +328,7 @@ __msan_unpoison(&ptr, sizeof(ptr)); #endif heap_->CheckAndMarkPointer(visitor, ptr); - VisitAsanFakeStackForPointer(visitor, ptr); + VisitAsanFakeStackForPointer(visitor, ptr, start_of_stack_, end_of_stack); } } @@ -1124,16 +1121,18 @@ using PushAllRegistersCallback = void (*)(ThreadState*, intptr_t*); extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback); -static void DidPushRegisters(ThreadState* state, intptr_t* stack_end) { - state->RecordStackEnd(stack_end); +// static +void ThreadState::VisitStackAfterPushingRegisters(ThreadState* state, + intptr_t* end_of_stack) { + state->VisitStack(static_cast<MarkingVisitor*>(state->CurrentVisitor()), + reinterpret_cast<Address*>(end_of_stack)); } void ThreadState::PushRegistersAndVisitStack() { DCHECK(CheckThread()); DCHECK(IsGCForbidden()); DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack); - PushAllRegisters(this, DidPushRegisters); - VisitStack(static_cast<MarkingVisitor*>(CurrentVisitor())); + PushAllRegisters(this, ThreadState::VisitStackAfterPushingRegisters); } void ThreadState::AddObserver(BlinkGCObserver* observer) {
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h index 69bb0a65..aec5fc7 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.h +++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -327,10 +327,6 @@ void SafePoint(BlinkGC::StackState); - void RecordStackEnd(intptr_t* end_of_stack) { end_of_stack_ = end_of_stack; } - - void PushRegistersAndVisitStack(); - // A region of non-weak PersistentNodes allocated on the given thread. PersistentRegion* GetPersistentRegion() const { return persistent_region_.get(); @@ -342,13 +338,6 @@ return weak_persistent_region_.get(); } - // Visit local thread stack and trace all pointers conservatively. - void VisitStack(MarkingVisitor*); - - // Visit the asan fake stack frame corresponding to a slot on the - // real machine stack if there is one. - void VisitAsanFakeStackForPointer(MarkingVisitor*, Address); - // Visit all non-weak persistents allocated on this thread. void VisitPersistents(Visitor*); @@ -453,6 +442,12 @@ // construct ThreadState in it using placement new. static uint8_t main_thread_state_storage_[]; + // Callback executed directly after pushing all callee-saved registers. + // |end_of_stack| denotes the end of the stack that can hold references to + // managed objects. + static void VisitStackAfterPushingRegisters(ThreadState*, + intptr_t* end_of_stack); + ThreadState(); ~ThreadState() override; @@ -510,6 +505,21 @@ bool MarkPhaseAdvanceMarking(base::TimeTicks deadline); void VerifyMarking(BlinkGC::MarkingType); + // Visit the stack after pushing registers onto the stack. + void PushRegistersAndVisitStack(); + + // Visit local thread stack and trace all pointers conservatively. Never call + // directly but always call through |PushRegistersAndVisitStack|. + void VisitStack(MarkingVisitor*, Address*); + + // Visit the asan fake stack frame corresponding to a slot on the real machine + // stack if there is one. Never call directly but always call through + // |PushRegistersAndVisitStack|. + void VisitAsanFakeStackForPointer(MarkingVisitor*, + Address, + Address*, + Address*); + // ShouldForceConservativeGC // implements the heuristics that are used to determine when to collect // garbage. @@ -576,8 +586,10 @@ base::PlatformThreadId thread_; std::unique_ptr<PersistentRegion> persistent_region_; std::unique_ptr<PersistentRegion> weak_persistent_region_; - intptr_t* start_of_stack_; - intptr_t* end_of_stack_; + + // Start of the stack which is the boundary until conservative stack scanning + // needs to search for managed pointers. + Address* start_of_stack_; bool in_atomic_pause_ = false; bool sweep_forbidden_ = false;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc index bee7c5e..8451bf1 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_error.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.cc
@@ -42,10 +42,6 @@ "information."; } // namespace -int ResourceError::BlockedByXSSAuditorErrorCode() { - return net::ERR_BLOCKED_BY_XSS_AUDITOR; -} - ResourceError ResourceError::CancelledError(const KURL& url) { return ResourceError(net::ERR_ABORTED, url, base::nullopt); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/third_party/blink/renderer/platform/loader/fetch/resource_error.h index d08439d..61cbc35 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_error.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.h
@@ -94,9 +94,6 @@ static bool Compare(const ResourceError&, const ResourceError&); - // Net error code getters are here to avoid unpreferred header inclusion. - static int BlockedByXSSAuditorErrorCode(); - private: void InitializeDescription();
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index f0cc716..020202c 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -139516,6 +139516,9 @@ "css/css-lists/nested-marker-ref.html": [ [] ], + "css/css-lists/parsing/counter-set-valid-expected.txt": [ + [] + ], "css/css-lists/parsing/list-style-image-computed.sub-expected.txt": [ [] ], @@ -200712,6 +200715,12 @@ {} ] ], + "css/css-animations/parsing/animation-name-computed.html": [ + [ + "css/css-animations/parsing/animation-name-computed.html", + {} + ] + ], "css/css-animations/parsing/animation-name-invalid.html": [ [ "css/css-animations/parsing/animation-name-invalid.html", @@ -205326,6 +205335,42 @@ {} ] ], + "css/css-lists/parsing/counter-increment-invalid.html": [ + [ + "css/css-lists/parsing/counter-increment-invalid.html", + {} + ] + ], + "css/css-lists/parsing/counter-increment-valid.html": [ + [ + "css/css-lists/parsing/counter-increment-valid.html", + {} + ] + ], + "css/css-lists/parsing/counter-reset-invalid.html": [ + [ + "css/css-lists/parsing/counter-reset-invalid.html", + {} + ] + ], + "css/css-lists/parsing/counter-reset-valid.html": [ + [ + "css/css-lists/parsing/counter-reset-valid.html", + {} + ] + ], + "css/css-lists/parsing/counter-set-invalid.html": [ + [ + "css/css-lists/parsing/counter-set-invalid.html", + {} + ] + ], + "css/css-lists/parsing/counter-set-valid.html": [ + [ + "css/css-lists/parsing/counter-set-valid.html", + {} + ] + ], "css/css-lists/parsing/list-style-computed.sub.html": [ [ "css/css-lists/parsing/list-style-computed.sub.html", @@ -320618,7 +320663,7 @@ "support" ], "README.md": [ - "5054889dc167880a75bc1b9bd3a49abed666b78f", + "919676ee21356e5c6b0efb3c88957a7baa3289bb", "support" ], "WebCryptoAPI/META.yml": [ @@ -344645,6 +344690,10 @@ "be8a83798908a6771b935e38fe7a8608be9821ed", "testharness" ], + "css/css-animations/parsing/animation-name-computed.html": [ + "a20aa7d99896b9ac6e9a5e7e319f278207327c8e", + "testharness" + ], "css/css-animations/parsing/animation-name-invalid-expected.txt": [ "a6d072671edbf2b2528754cf15f469eb7ce08d41", "support" @@ -348426,11 +348475,11 @@ "testharness" ], "css/css-box/inheritance-expected.txt": [ - "bb0e07753e649ffe3a0fbda7ba93985ef14bcf6a", + "c21b16bcf873d6bb4732f2bd980a7daa656eb367", "support" ], "css/css-box/inheritance.html": [ - "5047b8b1df07cb1c774b5f579101d69b2482058a", + "22443bf9a94e169a8fce1bd6cfeeead4a12b0ba3", "testharness" ], "css/css-box/parsing/clear-computed.html": [ @@ -366626,7 +366675,7 @@ "reftest" ], "css/css-layout-api/constraints-data-sab-failure.https.html": [ - "eb652d9a552ed0b4466245f5efba78835e55cf20", + "c03d35074aa6322057045de60fc7fb73d89c2456", "reftest" ], "css/css-layout-api/constraints-data.https.html": [ @@ -366842,7 +366891,7 @@ "reftest" ], "css/css-layout-api/fragment-data-sab-failure.https.html": [ - "59a9f835728e767b82cb8f147b856161914c6bf2", + "5d3619b3647df885005083504fe8d4dd81b2c6a8", "reftest" ], "css/css-layout-api/fragment-data.https.html": [ @@ -367249,6 +367298,34 @@ "9627ce936ae570325b430a1ac673cd66ae7d4252", "reftest" ], + "css/css-lists/parsing/counter-increment-invalid.html": [ + "262a38d76b57bb786268b42e8a9dc3df5b343f40", + "testharness" + ], + "css/css-lists/parsing/counter-increment-valid.html": [ + "277269000a21118a530f97ca5c2cb1061258933c", + "testharness" + ], + "css/css-lists/parsing/counter-reset-invalid.html": [ + "7a603fffc0d86226e6d56bd0b38c2069593191c4", + "testharness" + ], + "css/css-lists/parsing/counter-reset-valid.html": [ + "a71572289e41375e360b27a7ea7583538a2627d7", + "testharness" + ], + "css/css-lists/parsing/counter-set-invalid.html": [ + "9cc5be7c928305e647f97cdc360249dcba19b263", + "testharness" + ], + "css/css-lists/parsing/counter-set-valid-expected.txt": [ + "a56230af582117f3b0e159399bb86a49e410b1fd", + "support" + ], + "css/css-lists/parsing/counter-set-valid.html": [ + "3a4a16af92690ae1cc462b707c2e059146c0fcc7", + "testharness" + ], "css/css-lists/parsing/list-style-computed.sub.html": [ "611fae5bf93636cd4d3402e91b1cd47148303617", "testharness" @@ -444566,7 +444643,7 @@ "support" ], "interfaces/web-nfc.idl": [ - "f082a1e8952cbe6cad0e7e67fa8e7486135f90ba", + "d5fe1c085a2e3a127211c48cca97feb2410349a9", "support" ], "interfaces/web-share.idl": [ @@ -478070,7 +478147,7 @@ "support" ], "tools/certs/README.md": [ - "63119ba7f6c8e8f4a48b99eff62dbe1da0e61089", + "62c9d24685af8c00151b8fc804e6edca6d6c36d5", "support" ], "tools/certs/cacert.key": [
diff --git a/third_party/blink/web_tests/external/wpt/README.md b/third_party/blink/web_tests/external/wpt/README.md index 5054889..919676e 100644 --- a/third_party/blink/web_tests/external/wpt/README.md +++ b/third_party/blink/web_tests/external/wpt/README.md
@@ -180,76 +180,6 @@ line endings, as it will cause lint errors. For git, please set `git config core.autocrlf false` in your working tree. -Certificates -============ - -By default pre-generated certificates for the web-platform.test domain -are provided in [`tools/certs`](tools/certs). If you wish to generate new -certificates for any reason it's possible to use OpenSSL when starting -the server, or starting a test run, by providing the -`--ssl-type=openssl` argument to the `wpt serve` or `wpt run` -commands. - -If you installed OpenSSL in such a way that running `openssl` at a -command line doesn't work, you also need to adjust the path to the -OpenSSL binary. This can be done by adding a section to `config.json` -like: - -``` -"ssl": {"openssl": {"binary": "/path/to/openssl"}} -``` - -On Windows using OpenSSL typically requires installing an OpenSSL distribution. -[Shining Light](https://slproweb.com/products/Win32OpenSSL.html) -provide a convenient installer that is known to work, but requires a -little extra setup, i.e.: - -Run the installer for Win32_OpenSSL_v1.1.0b (30MB). During installation, -change the default location for where to Copy OpenSSL Dlls from the -System directory to the /bin directory. - -After installation, ensure that the path to OpenSSL (typically, -this will be `C:\OpenSSL-Win32\bin`) is in your `%Path%` -[Environment Variable](http://www.computerhope.com/issues/ch000549.htm). -If you forget to do this part, you will most likely see a 'File Not Found' -error when you start wptserve. - -Finally, set the path value in the server configuration file to the -default OpenSSL configuration file location. To do this create a file -called `config.json`. Then add the OpenSSL configuration below, -ensuring that the key `ssl/openssl/base_conf_path` has a value that is -the path to the OpenSSL config file (typically this will be -`C:\\OpenSSL-Win32\\bin\\openssl.cfg`): - -``` -{ - "ssl": { - "type": "openssl", - "encrypt_after_connect": false, - "openssl": { - "openssl_binary": "openssl", - "base_path: "_certs", - "force_regenerate": false, - "base_conf_path": "C:\\OpenSSL-Win32\\bin\\openssl.cfg" - }, - }, -} -``` - -### Trusting Root CA - -To prevent browser SSL warnings when running HTTPS tests locally, the -web-platform-tests Root CA file `cacert.pem` in [tools/certs](tools/certs) -must be added as a trusted certificate in your OS/browser. - -**NOTE**: The CA should not be installed in any browser profile used -outside of tests, since it may be used to generate fake -certificates. For browsers that use the OS certificate store, tests -should therefore not be run manually outside a dedicated OS instance -(e.g. a VM). To avoid this problem when running tests in Chrome or -Firefox use `wpt run`, which disables certificate checks and therefore -doesn't require the root CA to be trusted. - Publication =========== @@ -339,36 +269,6 @@ [lint-tool]: https://web-platform-tests.org/writing-tests/lint-tool.html -Adding command-line scripts ("tools" subdirs) ---------------------------------------------- - -Sometimes you may want to add a script to the repository that's meant -to be used from the command line, not from a browser (e.g., a script -for generating test files). If you want to ensure (e.g., for security -reasons) that such scripts won't be handled by the HTTP server, but -will instead only be usable from the command line, then place them in -either: - -* the `tools` subdir at the root of the repository, or - -* the `tools` subdir at the root of any top-level directory in the - repository which contains the tests the script is meant to be used - with - -Any files in those `tools` directories won't be handled by the HTTP -server; instead the server will return a 404 if a user navigates to -the URL for a file within them. - -If you want to add a script for use with a particular set of tests but -there isn't yet any `tools` subdir at the root of a top-level -directory in the repository containing those tests, you can create a -`tools` subdir at the root of that top-level directory and place your -scripts there. - -For example, if you wanted to add a script for use with tests in the -`notifications` directory, create the `notifications/tools` subdir and -put your script there. - Test Review ===========
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/constraints-data-sab-failure.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/constraints-data-sab-failure.https.html index eb652d9a..c03d3507 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-layout-api/constraints-data-sab-failure.https.html +++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/constraints-data-sab-failure.https.html
@@ -35,14 +35,9 @@ let childFragment = null; try { - // We need SABs to be enabled to properly run this test. - if (typeof SharedArrayBuffer !== 'undefined') { - childFragment = yield child.layoutNextFragment({ - data: { sab: new SharedArrayBuffer(4) } - }); - } else { - throw Error(); - } + childFragment = yield child.layoutNextFragment({ + data: { sab: new SharedArrayBuffer(4) } + }); } catch(e) { // Success! The structured cloning algorithm should have thrown an error. childFragment = yield child.layoutNextFragment({});
diff --git a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fragment-data-sab-failure.https.html b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fragment-data-sab-failure.https.html index 59a9f83..5d3619b3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-layout-api/fragment-data-sab-failure.https.html +++ b/third_party/blink/web_tests/external/wpt/css/css-layout-api/fragment-data-sab-failure.https.html
@@ -34,11 +34,7 @@ *layout(children, edges, constraints, styleMap) { const childFragments = yield children.map(child => child.layoutNextFragment()); - if (typeof SharedArrayBuffer !== 'undefined') { - return {autoBlockSize: 0, childFragments, data: {sab: new SharedArrayBuffer(4) }}; - } else { - throw Error(); - } + return {autoBlockSize: 0, childFragments, data: {sab: new SharedArrayBuffer(4) }}; } }); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-increment-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-increment-invalid.html new file mode 100644 index 0000000..262a38d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-increment-invalid.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: parsing counter-increment with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-increment"> +<meta name="assert" content="counter-increment supports only the grammar '[ <counter-name> <integer>? ]+ | none'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value('counter-increment', 'none chapter'); +test_invalid_value('counter-increment', '3'); +test_invalid_value('counter-increment', '99 imagenum'); +test_invalid_value('counter-increment', 'section -1, imagenum 99'); +test_invalid_value('counter-increment', 'section 3.14'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-increment-valid.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-increment-valid.html new file mode 100644 index 0000000..2772690 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-increment-valid.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: parsing counter-increment with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-increment"> +<meta name="assert" content="counter-increment supports the full grammar '[ <counter-name> <integer>? ]+ | none'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value('counter-increment', 'none'); +test_valid_value('counter-increment', 'chapter', 'chapter 1'); +test_valid_value('counter-increment', 'section -1'); +test_valid_value('counter-increment', 'first -1 second third 99', 'first -1 second 1 third 99'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-reset-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-reset-invalid.html new file mode 100644 index 0000000..7a603fff --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-reset-invalid.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: parsing counter-reset with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset"> +<meta name="assert" content="counter-reset supports only the grammar '[ <counter-name> <integer>? ]+ | none'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value('counter-reset', 'none chapter'); +test_invalid_value('counter-reset', '3'); +test_invalid_value('counter-reset', '99 imagenum'); +test_invalid_value('counter-reset', 'section -1, imagenum 99'); +test_invalid_value('counter-reset', 'section 3.14'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-reset-valid.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-reset-valid.html new file mode 100644 index 0000000..a715722 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-reset-valid.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: parsing counter-reset with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset"> +<meta name="assert" content="counter-reset supports the full grammar '[ <counter-name> <integer>? ]+ | none'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value('counter-reset', 'none'); +test_valid_value('counter-reset', 'chapter', 'chapter 0'); +test_valid_value('counter-reset', 'section -1'); +test_valid_value('counter-reset', 'first -1 second third 99', 'first -1 second 0 third 99'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-invalid.html new file mode 100644 index 0000000..9cc5be7c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-invalid.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: parsing counter-set with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-set"> +<meta name="assert" content="counter-set supports only the grammar '[ <counter-name> <integer>? ]+ | none'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value('counter-set', 'none chapter'); +test_invalid_value('counter-set', '3'); +test_invalid_value('counter-set', '99 imagenum'); +test_invalid_value('counter-set', 'section -1, imagenum 99'); +test_invalid_value('counter-set', 'section 3.14'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-valid-expected.txt new file mode 100644 index 0000000..a56230a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-valid-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +FAIL e.style['counter-set'] = "none" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['counter-set'] = "chapter" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['counter-set'] = "section -1" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['counter-set'] = "first -1 second third 99" should set the property value assert_not_equals: property should be set got disallowed value "" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-valid.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-valid.html new file mode 100644 index 0000000..3a4a16a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/counter-set-valid.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: parsing counter-set with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-counter-set"> +<meta name="assert" content="counter-set supports the full grammar '[ <counter-name> <integer>? ]+ | none'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_valid_value('counter-set', 'none'); +test_valid_value('counter-set', 'chapter', 'chapter 0'); +test_valid_value('counter-set', 'section -1'); +test_valid_value('counter-set', 'first -1 second third 99', 'first -1 second 0 third 99'); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl index f082a1e..d5fe1c0 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
@@ -33,13 +33,7 @@ NDEFRecordData data; }; -enum NDEFRecordType { - "empty", - "text", - "url", - "json", - "opaque" -}; +typedef DOMString NDEFRecordType; typedef (DOMString or ArrayBuffer or NDEFMessageInit) NDEFMessageSource;
diff --git a/third_party/blink/web_tests/external/wpt/tools/certs/README.md b/third_party/blink/web_tests/external/wpt/tools/certs/README.md index 63119ba..62c9d24 100644 --- a/third_party/blink/web_tests/external/wpt/tools/certs/README.md +++ b/third_party/blink/web_tests/external/wpt/tools/certs/README.md
@@ -1,11 +1,76 @@ -To enable https://web-platform.test:8443/, add cacert.pem to your browser as Certificate Authority. +# WPT Test Certificates + +The web-platform-tests project maintains a set of SSL certificates to allow +contributors to execute tests requiring HTTPS locally. + +## Trusting Root CA + +To prevent browser SSL warnings when running HTTPS tests locally, the +web-platform-tests Root CA file `cacert.pem` in the `tools/certs/` directory +must be added as a trusted certificate in your OS/browser. For Firefox, go to about:preferences and search for "certificates". -For browsers that use the Certificate Authorities of the underlying OS, such as Chrome and Safari, -you need to adjust the OS. For macOS, go to Keychain Access and add the certificate under -**login**. +For browsers that use the Certificate Authorities of the underlying OS, such as +Chrome and Safari, you need to adjust the OS. For macOS, go to Keychain Access +and add the certificate under **login**. -### Updating these certs +**NOTE**: The CA should not be installed in any browser profile used +outside of tests, since it may be used to generate fake +certificates. For browsers that use the OS certificate store, tests +should therefore not be run manually outside a dedicated OS instance +(e.g. a VM). To avoid this problem when running tests in Chrome or +Firefox, use `wpt run`, which disables certificate checks and therefore +doesn't require the root CA to be trusted. -From the root, run `./wpt serve --config tools/certs/config.json` and terminate it after it has started up. +## Regenerating certificates + +If you wish to generate new certificates for any reason, it's possible to use +OpenSSL when starting the server, or starting a test run, by providing the +`--ssl-type=openssl` argument to the `wpt serve` or `wpt run` commands. + +If you installed OpenSSL in such a way that running `openssl` at a +command line doesn't work, you also need to adjust the path to the +OpenSSL binary. This can be done by adding a section to `config.json` +like: + +``` +"ssl": {"openssl": {"binary": "/path/to/openssl"}} +``` + +On Windows using OpenSSL typically requires installing an OpenSSL distribution. +[Shining Light](https://slproweb.com/products/Win32OpenSSL.html) +provide a convenient installer that is known to work, but requires a +little extra setup, i.e.: + +Run the installer for Win32_OpenSSL_v1.1.0b (30MB). During installation, +change the default location for where to Copy OpenSSL Dlls from the +System directory to the /bin directory. + +After installation, ensure that the path to OpenSSL (typically, +this will be `C:\OpenSSL-Win32\bin`) is in your `%Path%` +[Environment Variable](http://www.computerhope.com/issues/ch000549.htm). +If you forget to do this part, you will most likely see a 'File Not Found' +error when you start wptserve. + +Finally, set the path value in the server configuration file to the +default OpenSSL configuration file location. To do this, create a file +called `config.json`. Then add the OpenSSL configuration below, +ensuring that the key `ssl/openssl/base_conf_path` has a value that is +the path to the OpenSSL config file (typically this will be +`C:\\OpenSSL-Win32\\bin\\openssl.cfg`): + +``` +{ + "ssl": { + "type": "openssl", + "encrypt_after_connect": false, + "openssl": { + "openssl_binary": "openssl", + "base_path: "_certs", + "force_regenerate": false, + "base_conf_path": "C:\\OpenSSL-Win32\\bin\\openssl.cfg" + }, + }, +} +```
diff --git a/third_party/custom_tabs_client/README.chromium b/third_party/custom_tabs_client/README.chromium index 0bf829b..95d433cc 100644 --- a/third_party/custom_tabs_client/README.chromium +++ b/third_party/custom_tabs_client/README.chromium
@@ -3,7 +3,7 @@ URL: https://chromium.googlesource.com/external/github.com/GoogleChrome/custom-tabs-client Version: unknown License: Apache 2.0 -Security Critical: yes +Security Critical: no License Android Compatible: yes Description: @@ -16,11 +16,4 @@ The example applicaton also presents how to use Browser Actions, including creating request intent and adding custom items. -The actual code that Chromium builds from is in -//third_party/android_sdk/androidx_browser, this subdirectory is kept around -for the example app (the custom_tabs_client_example_apk target). - -TODO(peconn): Get rid of src/customtabs and depend instead on -androidx_browser. - Local Modifications: None
diff --git a/third_party/feed/README.chromium b/third_party/feed/README.chromium index 58d8f488..33216ae 100644 --- a/third_party/feed/README.chromium +++ b/third_party/feed/README.chromium
@@ -2,7 +2,7 @@ Short name: feed URL: https://chromium.googlesource.com/feed Version: 0 -Revision: 4f87f10f5d5a589dbfd10815222d5d37fe267f06 +Revision: f4372718f4cabd57efeab02f5726ed147f29768f License: Apache 2.0 License File: LICENSE Security Critical: yes
diff --git a/tools/android/customtabs_benchmark/BUILD.gn b/tools/android/customtabs_benchmark/BUILD.gn index e8dec60..27cf5e0 100644 --- a/tools/android/customtabs_benchmark/BUILD.gn +++ b/tools/android/customtabs_benchmark/BUILD.gn
@@ -21,6 +21,6 @@ deps = [ ":customtabs_benchmark_apk_resources", "//third_party/android_deps:android_support_v4_java", - "//third_party/android_sdk/androidx_browser:androidx_browser_java", + "//third_party/custom_tabs_client:custom_tabs_support_java", ] }
diff --git a/tools/android/customtabs_benchmark/java/src/org/chromium/customtabs/test/MainActivity.java b/tools/android/customtabs_benchmark/java/src/org/chromium/customtabs/test/MainActivity.java index b16f4c13..3e205ec8 100644 --- a/tools/android/customtabs_benchmark/java/src/org/chromium/customtabs/test/MainActivity.java +++ b/tools/android/customtabs_benchmark/java/src/org/chromium/customtabs/test/MainActivity.java
@@ -18,6 +18,11 @@ import android.os.IBinder; import android.os.Looper; import android.os.SystemClock; +import android.support.customtabs.CustomTabsCallback; +import android.support.customtabs.CustomTabsClient; +import android.support.customtabs.CustomTabsIntent; +import android.support.customtabs.CustomTabsServiceConnection; +import android.support.customtabs.CustomTabsSession; import android.support.v4.app.BundleCompat; import android.util.Log; import android.view.View; @@ -34,12 +39,6 @@ import java.util.Random; import java.util.Set; -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsClient; -import androidx.browser.customtabs.CustomTabsIntent; -import androidx.browser.customtabs.CustomTabsServiceConnection; -import androidx.browser.customtabs.CustomTabsSession; - /** Activity used to benchmark Custom Tabs PLT. * * This activity contains benchmark code for two modes:
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index 17f6778..e9af384 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -114,8 +114,10 @@ <classpathentry kind="src" path="third_party/android_data_chart/java/src"/> <classpathentry kind="src" path="third_party/android_protobuf/src/java/src/main/java" including="com/google/protobuf/nano/*"/> <classpathentry kind="src" path="third_party/android_swipe_refresh/java/src"/> - <classpathentry kind="src" path="third_party/androidx_browser/src/browser/src"/> <classpathentry kind="src" path="third_party/cacheinvalidation/src/java"/> + <classpathentry kind="src" path="third_party/custom_tabs_client/src/customtabs/src"/> + <classpathentry kind="src" path="third_party/custom_tabs_client/src/Application/src/main/java"/> + <classpathentry kind="src" path="third_party/custom_tabs_client/src/shared/src/main/java"/> <classpathentry kind="src" path="third_party/gif_player/src"/> <classpathentry kind="src" path="third_party/junit/src/src/main/java"/> <classpathentry kind="src" path="third_party/mockito/src/src/main/java"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 13e7390..732a4aa 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -16957,8 +16957,10 @@ <owner>rhalavati@chromium.org</owner> <owner>chrome-privacy-core@google.com</owner> <summary> - Number of open guest browser windows at the same time. Recorded when a new - browser is created. + Number of open guest windows at the same time. Recorded when a new guest + window is created. Please note that this metric double counts the lower + numbers, meaning that if user opens three windows (without closing any in + between), then buckets 1, 2, and 3 will all be incremented in turn. </summary> </histogram> @@ -16966,8 +16968,10 @@ <owner>rhalavati@chromium.org</owner> <owner>chrome-privacy-core@google.com</owner> <summary> - Number of open incognito browser windows at the same time. Recorded when a - new browser is created. + Number of open incognito windows at the same time. Recorded when a new + incognito window is created. Please note that this metric double counts the + lower numbers, meaning that if user opens three windows (without closing any + in between), then buckets 1, 2, and 3 will all be incremented in turn. </summary> </histogram> @@ -130630,8 +130634,34 @@ </histogram> <histogram + name="SmartLock.Performance.AuthenticationToReceiveFirstRemoteStatusDuration.Unlock" + units="ms" expires_after="2020-07-23"> +<!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" --> + + <owner>hansberry@chromium.org</owner> + <owner>jhawkins@chromium.org</owner> + <summary> + The duration of time between when Smart Lock successfully establishes a + secure channel connection to the host device, and receives the initial + remote status from it -- this informs if the device can be unlocked on the + first remote status (i.e., if the Smart Lock icon is yellow or green). + + Suffixed by the type of remote status which was the first to be received. + View the base histogram to see results for all remote status types + aggregated together, and suffixed histograms for the results of just that + particular remote status type. + + See SmartLock.GetRemoteStatus.Unlock for the success rate of fetching the + remote status from the host. + </summary> +</histogram> + +<histogram name="SmartLock.Performance.AuthenticationToReceiveUnlockableRemoteStatus.Duration.Unlock" units="ms" expires_after="2020-02-01"> + <obsolete> + Removed 2019/08. + </obsolete> <owner>hansberry@chromium.org</owner> <summary> The duration of time between when Smart Lock successfully establishes a @@ -130642,8 +130672,64 @@ </histogram> <histogram + name="SmartLock.Performance.ShowLockScreenToShowFirstStatusToUserDuration.Unlock" + units="ms" expires_after="2020-07-23"> +<!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" --> + + <owner>hansberry@chromium.org</owner> + <owner>jhawkins@chromium.org</owner> + <summary> + The duration of time between when the user locks their screen or wakes their + device (either opening a clamshell device or waking up a tablet), and when + the user is first provided a visible indication of Smart Lock's status (the + Smart Lock icon presents as either yellow or green, with a tooltip + explaining the status). + + Suffixed by the type of status which the user is first presented with. View + the base histogram to see results for all status types aggregated together, + and suffixed histograms for the results of just that particular remote + status type. + + See SmartLock.GetRemoteStatus.Unlock for the success rate of fetching the + remote status from the host. + </summary> +</histogram> + +<histogram + name="SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration.Unlock" + units="ms" expires_after="2020-07-23"> +<!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" --> + + <owner>hansberry@chromium.org</owner> + <owner>jhawkins@chromium.org</owner> + <summary> + The duration of time between when Smart Lock begins to try to find the host + device, and receives the initial remote status from it -- this informs if + the device can be unlocked on the first remote status (i.e., if the Smart + Lock icon is yellow or green). + + Suffixed by the type of remote status which was the first to be received. + View the base histogram to see results for all remote status types + aggregated together, and suffixed histograms for the results of just that + particular remote status type. + + See + MultiDevice.SecureChannel.BLE.Performance.StartScanToAuthenticationDuration.Background + and + SmartLock.Performance.AuthenticationToReceiveFirstRemoteStatus.Unlock.Duration + for breakdowns of this metric. + + See SmartLock.GetRemoteStatus.Unlock for the success rate of fetching the + remote status from the host. + </summary> +</histogram> + +<histogram name="SmartLock.Performance.StartScanToReceiveUnlockableRemoteStatus.Duration.Unlock" units="ms" expires_after="2020-02-01"> + <obsolete> + Removed 2019/08. + </obsolete> <owner>hansberry@chromium.org</owner> <summary> The duration of time between when Smart Lock begins to try to find the host @@ -138056,7 +138142,12 @@ <owner>rhalavati@chromium.org</owner> <owner>chrome-privacy-core@google.com</owner> <summary> - Number of open tabs in each guest window. Recorded when a new tab is opened. + Number of open tabs in each guest window. Recorded once a new tab in a guest + window is opened and adds one to the bucket of number of tabs in that + particular window (it does not count the total number of tabs in all open + guest windows). Please note that this metric double counts the lower + numbers, meaning that if user opens three tabs (without closing any in + between), then buckets 1, 2, and 3 will all be incremented in turn. </summary> </histogram> @@ -138064,8 +138155,12 @@ <owner>rhalavati@chromium.org</owner> <owner>chrome-privacy-core@google.com</owner> <summary> - Number of open tabs in each incognito window. Recorded when a new tab is - opened. + Number of open tabs in each incognito window. Recorded once a new tab is + opened in an incognito window and adds one to the bucket of number of tabs + in that particular window (it does not count the total number of tabs in all + open incognito windows). Please note that this metric double counts the + lower numbers, meaning that if user opens three tabs (without closing any in + between), then buckets 1, 2, and 3 will all be incremented in turn. </summary> </histogram> @@ -143674,7 +143769,7 @@ </summary> </histogram> -<histogram name="UMA.LowEntropySource3Value" expires_after="2019-08-30"> +<histogram name="UMA.LowEntropySource3Value" expires_after="2020-08-30"> <owner>asvitkine@chromium.org</owner> <owner>mpearson@chromium.org</owner> <summary> @@ -143684,7 +143779,7 @@ </summary> </histogram> -<histogram name="UMA.LowEntropySourceValue" expires_after="2019-08-30"> +<histogram name="UMA.LowEntropySourceValue" expires_after="2020-03-01"> <owner>asvitkine@chromium.org</owner> <owner>mpearson@chromium.org</owner> <summary> @@ -169692,6 +169787,17 @@ <affected-histogram name="Skia.DrawScaleFactor"/> </histogram_suffixes> +<histogram_suffixes name="SmartLockStatusTypes" separator="."> + <suffix name="Other"/> + <suffix name="Unlockable"/> + <affected-histogram + name="SmartLock.Performance.AuthenticationToReceiveFirstRemoteStatusDuration.Unlock"/> + <affected-histogram + name="SmartLock.Performance.ShowLockScreenToShowFirstStatusToUserDuration.Unlock"/> + <affected-histogram + name="SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration.Unlock"/> +</histogram_suffixes> + <histogram_suffixes name="SmoothnessSequenceTypes" separator="."> <suffix name="CompositorAnimation" label="Compositor-driven animation"/> <suffix name="MainThreadAnimation" label="Main-thread driven animation"/>
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index 0d2e5c1f..ad2efc1 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -1793,6 +1793,8 @@ return "supportsTextLocation"; case ax::mojom::BoolAttribute::kIsLineBreakingObject: return "isLineBreakingObject"; + case ax::mojom::BoolAttribute::kIsPageBreakingObject: + return "isPageBreakingObject"; } return ""; @@ -1831,6 +1833,8 @@ return ax::mojom::BoolAttribute::kSupportsTextLocation; if (0 == strcmp(bool_attribute, "isLineBreakingObject")) return ax::mojom::BoolAttribute::kIsLineBreakingObject; + if (0 == strcmp(bool_attribute, "isPageBreakingObject")) + return ax::mojom::BoolAttribute::kIsPageBreakingObject; return ax::mojom::BoolAttribute::kNone; }
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index 05a962d..dfddc67 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -662,8 +662,10 @@ // given attribute, while another tree source only uses two. enum BoolAttribute { kNone, + // Generic busy state, does not have to be on a live region. kBusy, + // The object is at the root of an editable field, such as a content // editable. kEditableRoot, @@ -706,6 +708,9 @@ // Indicates whether this node causes a hard line-break // (e.g. block level elements, or <br>) kIsLineBreakingObject, + + // Indicates whether this node causes a page break + kIsPageBreakingObject, }; enum IntListAttribute {
diff --git a/ui/accessibility/ax_node.cc b/ui/accessibility/ax_node.cc index d8c510a..e7e564b 100644 --- a/ui/accessibility/ax_node.cc +++ b/ui/accessibility/ax_node.cc
@@ -56,7 +56,7 @@ AXNode* AXNode::GetUnignoredParent() const { DCHECK(!tree_->GetTreeUpdateInProgressState()); AXNode* result = parent(); - while (result && result->data().HasState(ax::mojom::State::kIgnored)) + while (result && result->IsIgnored()) result = result->parent(); return result; } @@ -83,7 +83,7 @@ while (parent_node) { if (index < parent_node->children().size()) { AXNode* child = parent_node->children()[index]; - if (!child->data().HasState(ax::mojom::State::kIgnored)) + if (!child->IsIgnored()) return child; // valid position (unignored child) // If the node is ignored, drill down to the ignored node's first child. @@ -92,7 +92,7 @@ } else { // If the parent is not ignored and we are past all of its children, there // is no next sibling. - if (!parent_node->data().HasState(ax::mojom::State::kIgnored)) + if (!parent_node->IsIgnored()) return nullptr; // If the parent is ignored and we are past all of its children, continue @@ -112,7 +112,7 @@ while (parent_node) { if (!before_first_child) { AXNode* child = parent_node->children()[index]; - if (!child->data().HasState(ax::mojom::State::kIgnored)) + if (!child->IsIgnored()) return child; // valid position (unignored child) // If the node is ignored, drill down to the ignored node's last child. @@ -122,7 +122,7 @@ } else { // If the parent is not ignored and we are past all of its children, there // is no next sibling. - if (!parent_node->data().HasState(ax::mojom::State::kIgnored)) + if (!parent_node->IsIgnored()) return nullptr; // If the parent is ignored and we are past all of its children, continue @@ -177,7 +177,7 @@ } void AXNode::UpdateUnignoredCachedValues() { - if (!data().HasState(ax::mojom::State::kIgnored)) + if (!IsIgnored()) UpdateUnignoredCachedValuesRecursive(0); } @@ -752,7 +752,7 @@ int AXNode::UpdateUnignoredCachedValuesRecursive(int startIndex) { int count = 0; for (AXNode* child : children_) { - if (child->data().HasState(ax::mojom::State::kIgnored)) { + if (child->IsIgnored()) { child->unignored_index_in_parent_ = 0; count += child->UpdateUnignoredCachedValuesRecursive(startIndex + count); } else { @@ -769,9 +769,8 @@ AXNode* result = parent(); // Continue walking up while parent is invalid, ignored, a generic container, // or unknown. - while (result && (result->data().HasState(ax::mojom::State::kIgnored) || + while (result && (result->IsIgnored() || result->data().role == ax::mojom::Role::kGenericContainer || - result->data().role == ax::mojom::Role::kIgnored || result->data().role == ax::mojom::Role::kUnknown)) { result = result->parent(); } @@ -785,7 +784,7 @@ for (int i = static_cast<int>(children().size()) - 1; i >= 0; --i) { AXNode* child = children_[i]; - if (!child->data().HasState(ax::mojom::State::kIgnored)) + if (!child->IsIgnored()) return child; AXNode* descendant = child->ComputeLastUnignoredChildRecursive(); @@ -799,7 +798,7 @@ DCHECK(!tree_->GetTreeUpdateInProgressState()); for (size_t i = 0; i < children().size(); i++) { AXNode* child = children_[i]; - if (!child->data().HasState(ax::mojom::State::kIgnored)) + if (!child->IsIgnored()) return child; AXNode* descendant = child->ComputeFirstUnignoredChildRecursive(); @@ -809,4 +808,8 @@ return nullptr; } +bool AXNode::IsIgnored() const { + return ui::IsIgnored(data()); +} + } // namespace ui
diff --git a/ui/accessibility/ax_node.h b/ui/accessibility/ax_node.h index b692a07..40814d27 100644 --- a/ui/accessibility/ax_node.h +++ b/ui/accessibility/ax_node.h
@@ -41,6 +41,7 @@ virtual int32_t GetSetSize(const AXNode& node, const AXNode* ordered_set) = 0; virtual bool GetTreeUpdateInProgressState() const = 0; + virtual bool HasPaginationSupport() const = 0; }; template <typename NodeType, @@ -349,6 +350,9 @@ // part of the language detection feature. void SetLanguageInfo(std::unique_ptr<AXLanguageInfo> lang_info); + // Returns true if node has ignored state or ignored role. + bool IsIgnored() const; + private: // Computes the text offset where each line starts by traversing all child // leaf nodes.
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc index 7775c4a..eca9ad0 100644 --- a/ui/accessibility/ax_node_data.cc +++ b/ui/accessibility/ax_node_data.cc
@@ -1428,6 +1428,9 @@ case ax::mojom::BoolAttribute::kIsLineBreakingObject: result += " is_line_breaking_object=" + value; break; + case ax::mojom::BoolAttribute::kIsPageBreakingObject: + result += " is_page_breaking_object=" + value; + break; case ax::mojom::BoolAttribute::kNone: break; }
diff --git a/ui/accessibility/ax_node_position_unittest.cc b/ui/accessibility/ax_node_position_unittest.cc index 6a60fce4..2d60ff6 100644 --- a/ui/accessibility/ax_node_position_unittest.cc +++ b/ui/accessibility/ax_node_position_unittest.cc
@@ -49,6 +49,68 @@ protected: void SetUp() override; void TearDown() override; + AXTree* CreateMultipageDocument(ui::AXNodeData& root_data, + ui::AXNodeData& page_1_data, + ui::AXNodeData& page_1_text_data, + ui::AXNodeData& page_2_data, + ui::AXNodeData& page_2_text_data, + ui::AXNodeData& page_3_data, + ui::AXNodeData& page_3_text_data) { + AXNodePosition::SetTreeForTesting(nullptr); + + root_data.id = 1; + root_data.role = ax::mojom::Role::kDocument; + + page_1_data.id = 2; + page_1_data.role = ax::mojom::Role::kRegion; + page_1_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject, true); + + page_1_text_data.id = 3; + page_1_text_data.role = ax::mojom::Role::kStaticText; + page_1_text_data.SetName("some text on page 1"); + page_1_text_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsLineBreakingObject, true); + page_1_data.child_ids = {3}; + + page_2_data.id = 4; + page_2_data.role = ax::mojom::Role::kRegion; + page_2_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject, true); + + page_2_text_data.id = 5; + page_2_text_data.role = ax::mojom::Role::kStaticText; + page_2_text_data.SetName("some text on page 2"); + page_2_text_data.AddIntAttribute( + ax::mojom::IntAttribute::kTextStyle, + static_cast<int32_t>(ax::mojom::TextStyle::kBold)); + page_2_data.child_ids = {5}; + + page_3_data.id = 6; + page_3_data.role = ax::mojom::Role::kRegion; + page_3_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject, true); + + page_3_text_data.id = 7; + page_3_text_data.role = ax::mojom::Role::kStaticText; + page_3_text_data.SetName("some more text on page 3"); + page_3_data.child_ids = {7}; + + root_data.child_ids = {2, 4, 6}; + + ui::AXTreeUpdate update; + ui::AXTreeData tree_data; + AXTreeID new_id = AXTreeID::CreateNewAXTreeID(); + tree_data.tree_id = new_id; + update.tree_data = tree_data; + update.has_tree_data = true; + update.root_id = root_data.id; + update.nodes = {root_data, page_1_data, page_1_text_data, + page_2_data, page_2_text_data, page_3_data, + page_3_text_data}; + + return new AXTree(update); + } void AssertTextLengthEquals(const AXTree* tree, int32_t node_id, @@ -137,6 +199,18 @@ const char* AXPositionTest::TEXT_VALUE = "Line 1\nLine 2"; void AXPositionTest::SetUp() { + // root_ + // | + // +------------+-----------+ + // | | | + // button_ check_box_ text_field_ + // | + // +-----------+------------+ + // | | | + // static_text1_ line_break_ static_text2_ + // | | + // inline_box1_ inline_box2_ + root_.id = ROOT_ID; button_.id = BUTTON_ID; check_box_.id = CHECK_BOX_ID; @@ -1617,6 +1691,279 @@ AXNodePosition::SetTreeForTesting(&tree_); } +TEST_F(AXPositionTest, CreatePositionAtPageBoundaryWithTextPosition) { + AXNodePosition::SetTreeForTesting(nullptr); + + ui::AXNodeData root_data, page_1_data, page_1_text_data, page_2_data, + page_2_text_data, page_3_data, page_3_text_data; + std::unique_ptr<ui::AXTree> new_tree(CreateMultipageDocument( + root_data, page_1_data, page_1_text_data, page_2_data, page_2_text_data, + page_3_data, page_3_text_data)); + AXNodePosition::SetTreeForTesting(new_tree.get()); + + // Test CreateNextPageStartPosition at the start of the document. + TestPositionType text_position = AXNodePosition::CreateTextPosition( + new_tree->data().tree_id, page_1_text_data.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, text_position); + TestPositionType test_position = text_position->CreateNextPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_1_text_data.id, test_position->anchor_id()); + EXPECT_EQ(19, test_position->text_offset()); + + // StopIfAlreadyAtBoundary shouldn't move at all since it's at a boundary + test_position = text_position->CreateNextPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_1_text_data.id, test_position->anchor_id()); + EXPECT_EQ(19, test_position->text_offset()); + + // Test CreateNextPageStartPosition until the end of document is reached + test_position = text_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + + test_position = test_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_3_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + + test_position = test_position->CreateNextPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_3_text_data.id, test_position->anchor_id()); + EXPECT_EQ(24, test_position->text_offset()); + + test_position = test_position->CreateNextPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_3_text_data.id, test_position->anchor_id()); + EXPECT_EQ(24, test_position->text_offset()); + + // Moving forward past the end should return a null position + TestPositionType null_position = test_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + null_position = test_position->CreateNextPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + // Now move backward through the document + test_position = test_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(19, test_position->text_offset()); + + test_position = test_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(19, test_position->text_offset()); + + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_1_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(page_1_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + + // Moving before the start should return a null position + null_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + null_position = test_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + AXNodePosition::SetTreeForTesting(&tree_); +} + +TEST_F(AXPositionTest, CreatePositionAtPageBoundaryWithTreePosition) { + AXNodePosition::SetTreeForTesting(nullptr); + ui::AXNodeData root_data, page_1_data, page_1_text_data, page_2_data, + page_2_text_data, page_3_data, page_3_text_data; + std::unique_ptr<ui::AXTree> new_tree(CreateMultipageDocument( + root_data, page_1_data, page_1_text_data, page_2_data, page_2_text_data, + page_3_data, page_3_text_data)); + AXNodePosition::SetTreeForTesting(new_tree.get()); + + // Test CreateNextPageStartPosition at the start of the document. + TestPositionType tree_position = AXNodePosition::CreateTreePosition( + new_tree->data().tree_id, page_1_data.id, 0 /* child_index */); + ASSERT_NE(nullptr, tree_position); + TestPositionType test_position = tree_position->CreateNextPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->child_index()); + + // StopIfAlreadyAtBoundary shouldn't move at all since it's at a boundary + test_position = tree_position->CreateNextPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_1_data.id, test_position->anchor_id()); + EXPECT_EQ(1, test_position->child_index()); + + // Test CreateNextPageStartPosition until the end of document is reached + test_position = tree_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index()); + + test_position = test_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_3_text_data.id, test_position->anchor_id()); + EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index()); + + test_position = test_position->CreateNextPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_3_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->child_index()); + + test_position = test_position->CreateNextPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_3_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->child_index()); + + // Moving forward past the end should return a null position + TestPositionType null_position = test_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + null_position = test_position->CreateNextPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + // Now move backward through the document + test_position = test_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->child_index()); + + test_position = test_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->child_index()); + + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index()); + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_2_text_data.id, test_position->anchor_id()); + EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index()); + + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_1_text_data.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(page_1_text_data.id, test_position->anchor_id()); + EXPECT_EQ(AXNodePosition::BEFORE_TEXT, test_position->child_index()); + + // Moving before the start should return a null position + null_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + null_position = test_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, null_position); + EXPECT_TRUE(null_position->IsNullPosition()); + + AXNodePosition::SetTreeForTesting(&tree_); +} + +TEST_F(AXPositionTest, CreatePagePositionWithNullPosition) { + TestPositionType null_position = AXNodePosition::CreateNullPosition(); + ASSERT_NE(nullptr, null_position); + TestPositionType test_position = + null_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + test_position = null_position->CreateNextPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + test_position = null_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + test_position = null_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); +} + TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithNullPosition) { TestPositionType null_position = AXNodePosition::CreateNullPosition(); ASSERT_NE(nullptr, null_position); @@ -1626,6 +1973,77 @@ EXPECT_TRUE(test_position->IsNullPosition()); } +TEST_F(AXPositionTest, CreatePagePositionWithNonPaginatedDocument) { + TestPositionType text_position = AXNodePosition::CreateTextPosition( + tree_.data().tree_id, static_text1_.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + ASSERT_NE(nullptr, text_position); + + // Non-paginated documents should move to the start of the document for + // CreatePreviousPageStartPosition (treating the entire document as a single + // page) + TestPositionType test_position = + text_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(button_.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + + // Since there is no next page, CreateNextPageStartPosition should return a + // null position + test_position = text_position->CreateNextPageStartPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + // Since there is no previous page, CreatePreviousPageEndPosition should + // return a null position + test_position = text_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + // Since there are no distinct pages, CreateNextPageEndPosition should move + // to the end of the document, as if it's one large page. + test_position = text_position->CreateNextPageEndPosition( + AXBoundaryBehavior::StopIfAlreadyAtBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(inline_box2_.id, test_position->anchor_id()); + EXPECT_EQ(6, test_position->text_offset()); + + // CreatePreviousPageStartPosition should move back to the beginning of the + // document + test_position = test_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsTextPosition()); + EXPECT_EQ(button_.id, test_position->anchor_id()); + EXPECT_EQ(0, test_position->text_offset()); + + // Since there's no next page, CreateNextPageStartPosition should return a + // null position + test_position = test_position->CreateNextPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + // Since there's no previous page, CreatePreviousPageEndPosition should return + // a null position + test_position = text_position->CreatePreviousPageEndPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); + + // Since there's no previous page, CreatePreviousPageStartPosition should + // return a null position + test_position = text_position->CreatePreviousPageStartPosition( + AXBoundaryBehavior::CrossBoundary); + EXPECT_NE(nullptr, test_position); + EXPECT_TRUE(test_position->IsNullPosition()); +} + TEST_F(AXPositionTest, CreatePositionAtStartOfDocumentWithTreePosition) { TestPositionType tree_position = AXNodePosition::CreateTreePosition( tree_.data().tree_id, root_.id, 0 /* child_index */); @@ -2033,6 +2451,110 @@ EXPECT_EQ(3, test_position->text_offset()); } +TEST_F(AXPositionTest, CreateNextLeafTreePosition) { + TestPositionType root_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, root_.id, 0 /* child_index */); + ASSERT_TRUE(root_position->IsTreePosition()); + + TestPositionType button_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, button_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType checkbox_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, check_box_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType inline_box1_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, inline_box1_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType line_break_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, line_break_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType inline_box2_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, inline_box2_.id, AXNodePosition::BEFORE_TEXT); + + TestPositionType test_position = root_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *button_position); + + test_position = test_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *checkbox_position); + + test_position = test_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *inline_box1_position); + + test_position = test_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *line_break_position); + + test_position = test_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *inline_box2_position); + + test_position = test_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsNullPosition()); + + TestPositionType root_text_position = AXNodePosition::CreateTextPosition( + tree_.data().tree_id, root_.id, 2 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + EXPECT_TRUE(root_text_position->IsTextPosition()); + + test_position = root_text_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *inline_box1_position); + + TestPositionType inline_box1_text_position = + AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box1_.id, + 2 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + EXPECT_TRUE(inline_box1_text_position->IsTextPosition()); + + test_position = inline_box1_text_position->CreateNextLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *line_break_position); +} + +TEST_F(AXPositionTest, CreatePreviousLeafTreePosition) { + TestPositionType inline_box2_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, inline_box2_.id, AXNodePosition::BEFORE_TEXT); + ASSERT_TRUE(inline_box2_position->IsTreePosition()); + + TestPositionType line_break_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, line_break_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType inline_box1_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, inline_box1_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType checkbox_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, check_box_.id, AXNodePosition::BEFORE_TEXT); + TestPositionType button_position = AXNodePosition::CreateTreePosition( + tree_.data().tree_id, button_.id, AXNodePosition::BEFORE_TEXT); + + TestPositionType test_position = + inline_box2_position->CreatePreviousLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *line_break_position); + + test_position = test_position->CreatePreviousLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *inline_box1_position); + + test_position = test_position->CreatePreviousLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *checkbox_position); + + test_position = test_position->CreatePreviousLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *button_position); + + test_position = test_position->CreatePreviousLeafTreePosition(); + EXPECT_TRUE(test_position->IsNullPosition()); + + TestPositionType inline_box2_text_position = + AXNodePosition::CreateTextPosition(tree_.data().tree_id, inline_box2_.id, + 2 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + EXPECT_TRUE(inline_box2_text_position->IsTextPosition()); + + test_position = inline_box2_text_position->CreatePreviousLeafTreePosition(); + EXPECT_TRUE(test_position->IsTreePosition()); + EXPECT_EQ(*test_position, *line_break_position); +} + TEST_F(AXPositionTest, AsPositionBeforeAndAfterCharacterWithNullPosition) { TestPositionType null_position = AXNodePosition::CreateNullPosition(); ASSERT_NE(nullptr, null_position);
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h index c5b2b9e..c048aac 100644 --- a/ui/accessibility/ax_position.h +++ b/ui/accessibility/ax_position.h
@@ -91,6 +91,9 @@ using AXPositionInstance = std::unique_ptr<AXPosition<AXPositionType, AXNodeType>>; + using BoundaryConditionPredicate = + base::RepeatingCallback<bool(const AXPositionInstance&)>; + static const int32_t INVALID_ANCHOR_ID = -1; static const int BEFORE_TEXT = -1; static const int INVALID_INDEX = -2; @@ -415,6 +418,59 @@ return false; } + bool AtStartOfPage() const { + AXPositionInstance text_position = AsLeafTextPosition(); + switch (text_position->kind_) { + case AXPositionKind::NULL_POSITION: + return false; + case AXPositionKind::TREE_POSITION: + NOTREACHED(); + return false; + case AXPositionKind::TEXT_POSITION: { + if (!text_position->AtStartOfAnchor()) + return false; + + // Search for the previous text position within the current page, + // using the page boundary abort predicate. + // If a valid position was found, then this position cannot be + // the start of a page. + // This will return a null position when an anchor movement would + // cross a page boundary, or the start of document was reached. + auto previous_text_position = + text_position->CreatePreviousTextAnchorPosition( + base::BindRepeating(&AbortMoveAtPageBoundary)); + return previous_text_position->IsNullPosition(); + } + } + return false; + } + + bool AtEndOfPage() const { + AXPositionInstance text_position = AsLeafTextPosition(); + switch (text_position->kind_) { + case AXPositionKind::NULL_POSITION: + return false; + case AXPositionKind::TREE_POSITION: + NOTREACHED(); + return false; + case AXPositionKind::TEXT_POSITION: { + if (!text_position->AtEndOfAnchor()) + return false; + + // Search for the next text position within the current page, + // using the page boundary abort predicate. + // If a valid position was found, then this position cannot be + // the end of a page. + // This will return a null position when an anchor movement would + // cross a page boundary, or the end of document was reached. + auto next_text_position = text_position->CreateNextTextAnchorPosition( + base::BindRepeating(&AbortMoveAtPageBoundary)); + return next_text_position->IsNullPosition(); + } + } + return false; + } + bool AtStartOfDocument() const { if (IsNullPosition()) return false; @@ -711,7 +767,7 @@ } AXPositionInstance CreatePositionAtStartOfDocument() const { - if (kind_ == AXPositionKind::NULL_POSITION) + if (IsNullPosition()) return CreateNullPosition(); AXPositionInstance iterator = Clone(); @@ -726,7 +782,7 @@ } AXPositionInstance CreatePositionAtEndOfDocument() const { - if (kind_ == AXPositionKind::NULL_POSITION) + if (IsNullPosition()) return CreateNullPosition(); AXPositionInstance iterator = Clone(); @@ -846,14 +902,40 @@ return CreateNullPosition(); } - // Creates a position using the next text-only node as its anchor. + // Creates a tree position using the next text-only node as its anchor. + // Assumes that text-only nodes are leaf nodes. + AXPositionInstance CreateNextLeafTreePosition() const { + AXPositionInstance next_leaf = AsTreePosition()->CreateNextAnchorPosition(); + while (!next_leaf->IsNullPosition() && next_leaf->AnchorChildCount()) { + next_leaf = next_leaf->CreateNextAnchorPosition(); + } + + DCHECK(next_leaf); + return next_leaf; + } + + // Creates a tree position using the previous text-only node as its anchor. + // Assumes that text-only nodes are leaf nodes. + AXPositionInstance CreatePreviousLeafTreePosition() const { + AXPositionInstance previous_leaf = + AsTreePosition()->CreatePreviousAnchorPosition(); + while (!previous_leaf->IsNullPosition() && + previous_leaf->AnchorChildCount()) { + previous_leaf = previous_leaf->CreatePreviousAnchorPosition(); + } + + DCHECK(previous_leaf); + return previous_leaf; + } + + // Creates a text position using the next text-only node as its anchor. // Assumes that text-only nodes are leaf nodes. AXPositionInstance CreateNextTextAnchorPosition() const { return CreateNextTextAnchorPosition( base::BindRepeating(&DefaultAbortMovePredicate)); } - // Creates a position using the previous text-only node as its anchor. + // Creates a text position using the previous text-only node as its anchor. // Assumes that text-only nodes are leaf nodes. AXPositionInstance CreatePreviousTextAnchorPosition() const { return CreatePreviousTextAnchorPosition( @@ -1420,12 +1502,70 @@ AXPositionInstance CreateNextParagraphStartPosition( AXBoundaryBehavior boundary_behavior) const { + return CreateNextBoundaryStartPosition( + boundary_behavior, base::BindRepeating(&AtStartOfParagraphPredicate), + base::BindRepeating(&AtEndOfParagraphPredicate)); + } + + AXPositionInstance CreatePreviousParagraphStartPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreatePreviousBoundaryStartPosition( + boundary_behavior, base::BindRepeating(&AtStartOfParagraphPredicate), + base::BindRepeating(&AtEndOfParagraphPredicate)); + } + + AXPositionInstance CreateNextParagraphEndPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreateNextBoundaryEndPosition( + boundary_behavior, base::BindRepeating(&AtStartOfParagraphPredicate), + base::BindRepeating(&AtEndOfParagraphPredicate)); + } + + AXPositionInstance CreatePreviousParagraphEndPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreatePreviousBoundaryEndPosition( + boundary_behavior, base::BindRepeating(&AtStartOfParagraphPredicate), + base::BindRepeating(&AtEndOfParagraphPredicate)); + } + + AXPositionInstance CreateNextPageStartPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreateNextBoundaryStartPosition( + boundary_behavior, base::BindRepeating(&AtStartOfPagePredicate), + base::BindRepeating(&AtEndOfPagePredicate)); + } + + AXPositionInstance CreatePreviousPageStartPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreatePreviousBoundaryStartPosition( + boundary_behavior, base::BindRepeating(&AtStartOfPagePredicate), + base::BindRepeating(&AtEndOfPagePredicate)); + } + + AXPositionInstance CreateNextPageEndPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreateNextBoundaryEndPosition( + boundary_behavior, base::BindRepeating(&AtStartOfPagePredicate), + base::BindRepeating(&AtEndOfPagePredicate)); + } + + AXPositionInstance CreatePreviousPageEndPosition( + AXBoundaryBehavior boundary_behavior) const { + return CreatePreviousBoundaryEndPosition( + boundary_behavior, base::BindRepeating(&AtStartOfPagePredicate), + base::BindRepeating(&AtEndOfPagePredicate)); + } + + AXPositionInstance CreateNextBoundaryStartPosition( + AXBoundaryBehavior boundary_behavior, + BoundaryConditionPredicate at_start_condition, + BoundaryConditionPredicate at_end_condition) const { bool was_tree_position = IsTreePosition(); AXPositionInstance text_position = AsLeafTextPosition(); if (text_position->IsNullPosition()) return text_position; if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary && - text_position->AtStartOfParagraph()) { + at_start_condition.Run(text_position)) { AXPositionInstance clone = Clone(); clone->affinity_ = ax::mojom::TextAffinity::kDownstream; return clone; @@ -1439,17 +1579,17 @@ return text_position; } - // Continue searching for the next paragraph start until the next logical + // Continue searching for the next boundary start until the next logical // text position is reached. } while ( - !text_position->AtStartOfParagraph() || + !at_start_condition.Run(text_position) || (boundary_behavior != AXBoundaryBehavior::StopIfAlreadyAtBoundary && *this == *text_position)); - // If the paragraph boundary is in the same subtree, return a position - // rooted at the current position. - // This is necessary because we don't want to return any position that might - // be in the shadow DOM if the original position was not. + // If the boundary is in the same subtree, return a position rooted at the + // current position. This is necessary because we don't want to return any + // position that might be in the shadow DOM if the original position was + // not. AXPositionInstance common_ancestor = text_position->LowestCommonAncestor(*this); if (GetAnchor() == common_ancestor->GetAnchor()) { @@ -1463,12 +1603,14 @@ return text_position; } - AXPositionInstance CreatePreviousParagraphStartPosition( - AXBoundaryBehavior boundary_behavior) const { + AXPositionInstance CreatePreviousBoundaryStartPosition( + AXBoundaryBehavior boundary_behavior, + BoundaryConditionPredicate at_start_condition, + BoundaryConditionPredicate at_end_condition) const { bool was_tree_position = IsTreePosition(); AXPositionInstance text_position = AsLeafTextPosition(); if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary && - text_position->AtStartOfParagraph()) { + at_start_condition.Run(text_position)) { AXPositionInstance clone = Clone(); clone->affinity_ = ax::mojom::TextAffinity::kDownstream; return clone; @@ -1487,17 +1629,17 @@ return text_position; } - // Continue searching for the previous paragraph start until the next + // Continue searching for the previous page start until the next // logical text position is reached. } while ( - !text_position->AtStartOfParagraph() || + !at_start_condition.Run(text_position) || (boundary_behavior != AXBoundaryBehavior::StopIfAlreadyAtBoundary && *this == *text_position)); - // If the paragraph boundary is in the same subtree, return a position - // rooted at the current position. - // This is necessary because we don't want to return any position that might - // be in the shadow DOM if the original position was not. + // If the boundary is in the same subtree, return a position rooted at the + // current position. This is necessary because we don't want to return any + // position that might be in the shadow DOM if the original position was + // not. AXPositionInstance common_ancestor = text_position->LowestCommonAncestor(*this); if (GetAnchor() == common_ancestor->GetAnchor()) { @@ -1511,19 +1653,21 @@ return text_position; } - AXPositionInstance CreateNextParagraphEndPosition( - AXBoundaryBehavior boundary_behavior) const { + AXPositionInstance CreateNextBoundaryEndPosition( + AXBoundaryBehavior boundary_behavior, + BoundaryConditionPredicate at_start_condition, + BoundaryConditionPredicate at_end_condition) const { bool was_tree_position = IsTreePosition(); AXPositionInstance text_position = AsLeafTextPosition(); if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary && - text_position->AtEndOfParagraph()) { + at_end_condition.Run(text_position)) { AXPositionInstance clone = Clone(); // If there is no ambiguity as to whether the position is at the end of - // the current paragraph or the start of the next paragraph, affinity + // the current boundary or the start of the next boundary, affinity // should be reset in order to get consistent output from this function // regardless of input affinity. clone->affinity_ = ax::mojom::TextAffinity::kDownstream; - if (clone->AtStartOfParagraph()) + if (at_start_condition.Run(clone)) clone->affinity_ = ax::mojom::TextAffinity::kUpstream; return clone; } @@ -1542,17 +1686,17 @@ return text_position; } - // Continue searching for the next paragraph end until the next logical + // Continue searching for the next boundary end until the next logical // text position is reached. } while ( - !text_position->AtEndOfParagraph() || + !at_end_condition.Run(text_position) || (boundary_behavior != AXBoundaryBehavior::StopIfAlreadyAtBoundary && *this == *text_position)); - // If the paragraph boundary is in the same subtree, return a position - // rooted at the current position. - // This is necessary because we don't want to return any position that might - // be in the shadow DOM if the original position was not. + // If the boundary is in the same subtree, return a position rooted at the + // current position. This is necessary because we don't want to return any + // position that might be in the shadow DOM if the original position was + // not. AXPositionInstance common_ancestor = text_position->LowestCommonAncestor(*this); if (GetAnchor() == common_ancestor->GetAnchor()) { @@ -1566,21 +1710,23 @@ return text_position; } - AXPositionInstance CreatePreviousParagraphEndPosition( - AXBoundaryBehavior boundary_behavior) const { + AXPositionInstance CreatePreviousBoundaryEndPosition( + AXBoundaryBehavior boundary_behavior, + BoundaryConditionPredicate at_start_condition, + BoundaryConditionPredicate at_end_condition) const { bool was_tree_position = IsTreePosition(); AXPositionInstance text_position = AsLeafTextPosition(); if (text_position->IsNullPosition()) return text_position; if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary && - text_position->AtEndOfParagraph()) { + at_end_condition.Run(text_position)) { AXPositionInstance clone = Clone(); // If there is no ambiguity as to whether the position is at the end of - // the current line or the start of the next line, affinity should be - // reset in order to get consistent output from this function regardless - // of input affinity. + // the current boundary or the start of the next boundary, affinity + // should be reset in order to get consistent output from this function + // regardless of input affinity. clone->affinity_ = ax::mojom::TextAffinity::kDownstream; - if (clone->AtStartOfParagraph()) + if (at_start_condition.Run(clone)) clone->affinity_ = ax::mojom::TextAffinity::kUpstream; return clone; } @@ -1594,17 +1740,17 @@ return text_position; } - // Continue searching for the previous paragraph end until the next + // Continue searching for the previous boundary end until the next // logical text position is reached. } while ( - !text_position->AtEndOfParagraph() || + !at_end_condition.Run(text_position) || (boundary_behavior != AXBoundaryBehavior::StopIfAlreadyAtBoundary && *this == *text_position)); - // If the paragraph boundary is in the same subtree, return a position - // rooted at the current position. - // This is necessary because we don't want to return any position that might - // be in the shadow DOM if the original position was not. + // If the boundary is in the same subtree, return a position rooted at the + // current position. This is necessary because we don't want to return any + // position that might be in the shadow DOM if the original position was + // not. AXPositionInstance common_ancestor = text_position->LowestCommonAncestor(*this); if (GetAnchor() == common_ancestor->GetAnchor()) { @@ -2025,6 +2171,31 @@ return previous_leaf->AsLeafTextPosition(); } + // Static helpers for lambda usage + static bool AtStartOfParagraphPredicate(const AXPositionInstance& position) { + return position->AtStartOfParagraph(); + } + + static bool AtEndOfParagraphPredicate(const AXPositionInstance& position) { + return position->AtEndOfParagraph(); + } + + static bool AtStartOfPagePredicate(const AXPositionInstance& position) { + return position->AtStartOfPage(); + } + + static bool AtEndOfPagePredicate(const AXPositionInstance& position) { + return position->AtEndOfPage(); + } + + static bool AtStartOfLinePredicate(const AXPositionInstance& position) { + return position->AtStartOfLine(); + } + + static bool AtEndOfLinePredicate(const AXPositionInstance& position) { + return position->AtEndOfLine(); + } + // Default behavior is to never abort static bool DefaultAbortMovePredicate( const AXPosition<AXPositionType, AXNodeType>& move_from, @@ -2094,6 +2265,40 @@ return false; } + // AbortMovePredicate function used to detect page boundaries. + static bool AbortMoveAtPageBoundary( + const AXPosition<AXPositionType, AXNodeType>& move_from, + const AXPosition<AXPositionType, AXNodeType>& move_to, + const AXMoveType move_type, + const AXMoveDirection direction) { + if (move_from.IsNullPosition() || move_to.IsNullPosition()) + return true; + + const bool move_from_break = move_from.GetAnchor()->data().GetBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject); + const bool move_to_break = move_to.GetAnchor()->data().GetBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject); + + switch (move_type) { + case AXMoveType::kAncestor: + // For Ancestor moves, only abort when exiting a page break. + // We don't care if the ancestor is a page break or not, since the + // descendant is contained by it. + return move_from_break; + case AXMoveType::kDescendant: + // For Descendant moves, only abort when entering a page break + // descendant. We don't care if the ancestor is a page break or not, + // since the descendant is contained by it. + return move_to_break; + case AXMoveType::kSibling: + // For Sibling moves, abort if at both of the siblings are a page + // break, because that would mean exiting and/or entering a page break. + return move_from_break && move_to_break; + } + + return false; + } + AXPositionKind kind_; AXTreeID tree_id_; int32_t anchor_id_;
diff --git a/ui/accessibility/ax_range.h b/ui/accessibility/ax_range.h index dc53794..62e4880 100644 --- a/ui/accessibility/ax_range.h +++ b/ui/accessibility/ax_range.h
@@ -182,8 +182,7 @@ if (current_start_->GetAnchor() == iterator_end_->GetAnchor()) { current_start_ = AXPositionType::CreateNullPosition(); } else { - current_start_ = - current_start_->CreateNextAnchorPosition()->AsLeafTextPosition(); + current_start_ = current_start_->CreateNextLeafTreePosition(); DCHECK_LE(*current_start_, *iterator_end_); } return *this; @@ -197,8 +196,8 @@ : iterator_end_->Clone(); DCHECK_LE(*current_end, *iterator_end_); - AXRange current_leaf_text_range(current_start_->Clone(), - std::move(current_end)); + AXRange current_leaf_text_range(current_start_->AsTextPosition(), + current_end->AsTextPosition()); DCHECK(current_leaf_text_range.IsLeafTextRange()); return std::move(current_leaf_text_range); }
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index c0075b1b..f8e8893 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -138,6 +138,7 @@ bool IsDocument(const ax::mojom::Role role) { switch (role) { + case ax::mojom::Role::kDocument: case ax::mojom::Role::kRootWebArea: case ax::mojom::Role::kWebArea: return true; @@ -168,6 +169,13 @@ } } +bool IsIgnored(const AXNodeData& data) { + if (data.HasState(ax::mojom::State::kIgnored) || + data.role == ax::mojom::Role::kIgnored) + return true; + return false; +} + bool IsImage(const ax::mojom::Role role) { switch (role) { case ax::mojom::Role::kCanvas:
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index b5c3ae9..d017543 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -43,6 +43,9 @@ // Returns true if the provided role belongs to a heading or a table header. AX_EXPORT bool IsHeadingOrTableHeader(const ax::mojom::Role role); +// Returns true if the given AXNodeData has ignored state or ignored role. +AX_EXPORT bool IsIgnored(const AXNodeData& data); + // Returns true if the provided role belongs to an image, graphic, canvas, etc. AX_EXPORT bool IsImage(const ax::mojom::Role role);
diff --git a/ui/accessibility/ax_serializable_tree.cc b/ui/accessibility/ax_serializable_tree.cc index f2473aa..4ad26d7 100644 --- a/ui/accessibility/ax_serializable_tree.cc +++ b/ui/accessibility/ax_serializable_tree.cc
@@ -45,7 +45,7 @@ } bool IsIgnored(const AXNode* node) const override { - return node->data().HasState(ax::mojom::State::kIgnored); + return node->IsIgnored(); } bool IsValid(const AXNode* node) const override { return node != nullptr; }
diff --git a/ui/accessibility/ax_table_info.cc b/ui/accessibility/ax_table_info.cc index dc8b2d3..f1a6485 100644 --- a/ui/accessibility/ax_table_info.cc +++ b/ui/accessibility/ax_table_info.cc
@@ -26,7 +26,7 @@ // in-between a table row and its cells. void FindCellsInRow(AXNode* node, std::vector<AXNode*>* cell_nodes) { for (AXNode* child : node->children()) { - if (child->data().HasState(ax::mojom::State::kIgnored) || + if (child->IsIgnored() || child->data().role == ax::mojom::Role::kGenericContainer) FindCellsInRow(child, cell_nodes); else if (IsCellOrTableHeader(child->data().role)) @@ -47,7 +47,7 @@ std::vector<std::vector<AXNode*>>* cell_nodes_per_row, int32_t& caption_node_id) { for (AXNode* child : node->children()) { - if (child->data().HasState(ax::mojom::State::kIgnored) || + if (child->IsIgnored() || child->data().role == ax::mojom::Role::kGenericContainer || child->data().role == ax::mojom::Role::kGroup) { FindRowsAndThenCells(child, row_nodes, cell_nodes_per_row,
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 5352b9d0..ac5e3a40 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -1280,6 +1280,10 @@ node->SetData(src); } + // If we come across a page breaking object, mark the tree as a paginated root + if (src.GetBoolAttribute(ax::mojom::BoolAttribute::kIsPageBreakingObject)) + has_pagination_support_ = true; + update_state->node_data_changed_ids.insert(node->id()); // First, delete nodes that used to be children of this node but aren't @@ -1724,7 +1728,7 @@ std::vector<const AXNode*>& items, const AXNode& original_node) const { // Ignored nodes are not a part of ordered sets. - if (original_node.data().HasState(ax::mojom::State::kIgnored)) + if (original_node.IsIgnored()) return; // Stop searching current path if roles of local_parent and ordered set match. @@ -1803,8 +1807,8 @@ items.push_back(child); // Recurse if there is a generic container, ignored, or unknown. - if (child->data().role == ax::mojom::Role::kGenericContainer || - child->data().role == ax::mojom::Role::kIgnored || + if (child->IsIgnored() || + child->data().role == ax::mojom::Role::kGenericContainer || child->data().role == ax::mojom::Role::kUnknown) { PopulateOrderedSetItems(ordered_set, child, items, original_node); } @@ -1960,4 +1964,8 @@ tree_update_in_progress_ = set_tree_update_value; } +bool AXTree::HasPaginationSupport() const { + return has_pagination_support_; +} + } // namespace ui
diff --git a/ui/accessibility/ax_tree.h b/ui/accessibility/ax_tree.h index b2dfc3c..d20a32df 100644 --- a/ui/accessibility/ax_tree.h +++ b/ui/accessibility/ax_tree.h
@@ -150,6 +150,10 @@ bool GetTreeUpdateInProgressState() const override; void SetTreeUpdateInProgressState(bool set_tree_update_value); + // AXNode::OwnerTree override. + // Returns true if the tree represents a paginated document + bool HasPaginationSupport() const override; + // Language detection manager, entry point to language detection features. // TODO(chrishall): Should this be stored by pointer or value? // When should we initialize this? @@ -327,6 +331,9 @@ // Indicates if the tree is updating. bool tree_update_in_progress_ = false; + + // Indicates if the tree represents a paginated document + bool has_pagination_support_ = false; }; } // namespace ui
diff --git a/ui/accessibility/ax_tree_serializer_unittest.cc b/ui/accessibility/ax_tree_serializer_unittest.cc index d305964..814accfd 100644 --- a/ui/accessibility/ax_tree_serializer_unittest.cc +++ b/ui/accessibility/ax_tree_serializer_unittest.cc
@@ -263,7 +263,7 @@ return node->parent(); } bool IsIgnored(const AXNode* node) const override { - return node->data().HasState(ax::mojom::State::kIgnored); + return node->IsIgnored(); } bool IsValid(const AXNode* node) const override { return node != nullptr && node->id() != invalid_id_;
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index c9967e7..e7f39053 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -3237,7 +3237,7 @@ void AXPlatformNodeAuraLinux::OnSubtreeCreated() { // We might not have a parent, in that case we don't need to send the event. // We also don't want to notify if this is an ignored node - if (!GetParent() || GetData().HasState(ax::mojom::State::kIgnored)) + if (!GetParent() || ui::IsIgnored(GetData())) return; g_signal_emit_by_name(GetParent(), "children-changed::add", GetIndexInParent(), GetOrCreateAtkObject()); @@ -3246,7 +3246,7 @@ void AXPlatformNodeAuraLinux::OnSubtreeWillBeDeleted() { // There is a chance there won't be a parent as we're in the deletion process. // We also don't want to notify if this is an ignored node - if (!GetParent() || GetData().HasState(ax::mojom::State::kIgnored)) + if (!GetParent() || ui::IsIgnored(GetData())) return; g_signal_emit_by_name(GetParent(), "children-changed::remove",
diff --git a/ui/accessibility/platform/ax_platform_node_base.cc b/ui/accessibility/platform/ax_platform_node_base.cc index 16c0257..fe081ae 100644 --- a/ui/accessibility/platform/ax_platform_node_base.cc +++ b/ui/accessibility/platform/ax_platform_node_base.cc
@@ -725,9 +725,7 @@ bool AXPlatformNodeBase::IsInvisibleOrIgnored() const { const AXNodeData& data = GetData(); - return data.HasState(ax::mojom::State::kInvisible) || - data.HasState(ax::mojom::State::kIgnored) || - data.role == ax::mojom::Role::kIgnored; + return data.HasState(ax::mojom::State::kInvisible) || ui::IsIgnored(data); } bool AXPlatformNodeBase::IsScrollable() const {
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc index 63c1d43..312fe58 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.cc
@@ -178,10 +178,19 @@ end_ = start_->CreateNextParagraphEndPosition( AXBoundaryBehavior::StopIfAlreadyAtBoundary); break; - - // Since web content is not paginated, TextUnit_Page is not supported. - // Substituting it by the next larger unit: TextUnit_Document. - case TextUnit_Page: + case TextUnit_Page: { + // If the document doesn't support pagination, default to document units + // per UIA spec + AXPositionInstance common_ancestor = start_->LowestCommonAncestor(*end_); + if (common_ancestor->GetAnchor()->tree()->HasPaginationSupport()) { + start_ = start_->CreatePreviousPageStartPosition( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); + end_ = start_->CreateNextPageEndPosition( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); + break; + } + } + FALLTHROUGH; case TextUnit_Document: start_ = start_->CreatePositionAtStartOfDocument()->AsLeafTextPosition(); end_ = start_->CreatePositionAtEndOfDocument(); @@ -586,9 +595,10 @@ new_position = MoveEndpointByParagraph( position_to_move, is_start_endpoint, count, units_moved); break; - // Since web content is not paginated, TextUnit_Page is not supported. - // Substituting it by the next larger unit: TextUnit_Document. case TextUnit_Page: + new_position = MoveEndpointByPage(position_to_move, is_start_endpoint, + count, units_moved); + break; case TextUnit_Document: new_position = MoveEndpointByDocument(position_to_move, count, units_moved); @@ -930,6 +940,53 @@ } AXPlatformNodeTextRangeProviderWin::AXPositionInstance +AXPlatformNodeTextRangeProviderWin::MoveEndpointByPage( + const AXNodePosition::AXPositionInstance& endpoint, + const bool is_start_endpoint, + const int count, + int* count_moved) { + // If the document doesn't support pagination, default to document navigation + // per UIA spec + AXPositionInstance common_ancestor = start_->LowestCommonAncestor(*end_); + if (!common_ancestor->GetAnchor()->tree()->HasPaginationSupport()) + return MoveEndpointByDocument(std::move(endpoint), count, count_moved); + + auto current_endpoint = endpoint->Clone(); + const bool forwards = count > 0; + const int count_abs = std::abs(count); + const auto behavior = ui::AXBoundaryBehavior::CrossBoundary; + int iteration = 0; + for (iteration = 0; iteration < count_abs; ++iteration) { + AXPositionInstance next_endpoint; + if (forwards) { + next_endpoint = + is_start_endpoint + ? current_endpoint->CreateNextPageStartPosition(behavior) + : current_endpoint->CreateNextPageEndPosition(behavior); + } else { + next_endpoint = + is_start_endpoint + ? current_endpoint->CreatePreviousPageStartPosition(behavior) + : current_endpoint->CreatePreviousPageEndPosition(behavior); + } + // End of document + if (next_endpoint->IsNullPosition()) { + int document_moved; + next_endpoint = MoveEndpointByDocument(endpoint, count, &document_moved); + if (*endpoint != *next_endpoint && !next_endpoint->IsNullPosition()) { + ++iteration; + current_endpoint = std::move(next_endpoint); + } + break; + } + current_endpoint = std::move(next_endpoint); + } + + *count_moved = (forwards) ? iteration : -iteration; + return current_endpoint; +} + +AXPlatformNodeTextRangeProviderWin::AXPositionInstance AXPlatformNodeTextRangeProviderWin::MoveEndpointByDocument( const AXPositionInstance& endpoint, const int count,
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h index 3e8c4d3..f39cc51d 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h
@@ -115,6 +115,10 @@ const bool is_start_endpoint, const int count, int* count_moved); + AXPositionInstance MoveEndpointByPage(const AXPositionInstance& endpoint, + const bool is_start_endpoint, + const int count, + int* count_moved); AXPositionInstance MoveEndpointByFormat(const AXPositionInstance& endpoint, const int count, int* units_moved);
diff --git a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc index b95ad50..250f0ce 100644 --- a/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc +++ b/ui/accessibility/platform/ax_platform_node_textrangeprovider_win_unittest.cc
@@ -669,6 +669,67 @@ return update; } + + ui::AXTreeUpdate BuildAXTreeForMoveByPage() { + ui::AXNodeData root_data; + root_data.id = 1; + root_data.role = ax::mojom::Role::kDocument; + + ui::AXNodeData page_1_data; + page_1_data.id = 2; + page_1_data.role = ax::mojom::Role::kRegion; + page_1_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject, true); + + ui::AXNodeData page_1_text_data; + page_1_text_data.id = 3; + page_1_text_data.role = ax::mojom::Role::kStaticText; + page_1_text_data.SetName("some text on page 1"); + page_1_text_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsLineBreakingObject, true); + page_1_data.child_ids = {3}; + + ui::AXNodeData page_2_data; + page_2_data.id = 4; + page_2_data.role = ax::mojom::Role::kRegion; + page_2_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject, true); + + ui::AXNodeData page_2_text_data; + page_2_text_data.id = 5; + page_2_text_data.role = ax::mojom::Role::kStaticText; + page_2_text_data.SetName("some text on page 2"); + page_2_text_data.AddIntAttribute( + ax::mojom::IntAttribute::kTextStyle, + static_cast<int32_t>(ax::mojom::TextStyle::kBold)); + page_2_data.child_ids = {5}; + + ui::AXNodeData page_3_data; + page_3_data.id = 6; + page_3_data.role = ax::mojom::Role::kRegion; + page_3_data.AddBoolAttribute( + ax::mojom::BoolAttribute::kIsPageBreakingObject, true); + + ui::AXNodeData page_3_text_data; + page_3_text_data.id = 7; + page_3_text_data.role = ax::mojom::Role::kStaticText; + page_3_text_data.SetName("some more text on page 3"); + page_3_data.child_ids = {7}; + + root_data.child_ids = {2, 4, 6}; + + ui::AXTreeUpdate update; + ui::AXTreeData tree_data; + tree_data.tree_id = ui::AXTreeID::CreateNewAXTreeID(); + update.tree_data = tree_data; + update.has_tree_data = true; + update.root_id = root_data.id; + update.nodes = {root_data, page_1_data, page_1_text_data, + page_2_data, page_2_text_data, page_3_data, + page_3_text_data}; + + return update; + } }; class MockAXPlatformNodeTextRangeProviderWin @@ -1560,6 +1621,85 @@ AXNodePosition::SetTreeForTesting(nullptr); } +TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMovePage) { + Init(BuildAXTreeForMoveByPage()); + AXNode* root_node = GetRootNode(); + AXNodePosition::SetTreeForTesting(tree_.get()); + + ComPtr<ITextRangeProvider> text_range_provider; + GetTextRangeProviderFromTextNode(text_range_provider, root_node); + + // Moving by 0 should have no effect. + EXPECT_UIA_MOVE( + text_range_provider, TextUnit_Page, + /*count*/ 0, + /*expected_text*/ + L"some text on page 1\nsome text on page 2some more text on page 3", + /*expected_count*/ 0); + + // Backwards endpoint moves + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Page, + /*count*/ -1, + /*expected_text*/ L"some text on page 1\nsome text on page 2", + /*expected_count*/ -1); + + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT(text_range_provider, + TextPatternRangeEndpoint_End, TextUnit_Page, + /*count*/ -5, + /*expected_text*/ L"", + /*expected_count*/ -2); + + // Forwards endpoint move + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Page, + /*count*/ 5, + /*expected_text*/ + L"some text on page 1\nsome text on page 2some more text on page 3", + /*expected_count*/ 4); + + // Range moves + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page, + /*count*/ 1, + /*expected_text*/ L"some text on page 2", + /*expected_count*/ 1); + + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page, + /*count*/ 1, + /*expected_text*/ L"some more text on page 3", + /*expected_count*/ 1); + + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page, + /*count*/ -1, + /*expected_text*/ L"some text on page 2", + /*expected_count*/ -1); + + // ExpandToEnclosingUnit - first move by character so it's not on a + // page boundary before calling ExpandToEnclosingUnit + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_End, TextUnit_Character, + /*count*/ -2, + /*expected_text*/ L"some text on page", + /*expected_count*/ -2); + + EXPECT_UIA_MOVE_ENDPOINT_BY_UNIT( + text_range_provider, TextPatternRangeEndpoint_Start, TextUnit_Character, + /*count*/ 2, + /*expected_text*/ L"me text on page", + /*expected_count*/ 2); + + ASSERT_HRESULT_SUCCEEDED( + text_range_provider->ExpandToEnclosingUnit(TextUnit_Page)); + + EXPECT_UIA_MOVE(text_range_provider, TextUnit_Page, + /*count*/ 0, + /*expected_text*/ + L"some text on page 2", + /*expected_count*/ 0); + + AXNodePosition::SetTreeForTesting(nullptr); +} + TEST_F(AXPlatformNodeTextRangeProviderTest, TestITextRangeProviderMoveWord) { Init(BuildAXTreeForMove()); AXNode* root_node = GetRootNode();
diff --git a/ui/base/clipboard/OWNERS b/ui/base/clipboard/OWNERS index c1468a7..4a0f01a 100644 --- a/ui/base/clipboard/OWNERS +++ b/ui/base/clipboard/OWNERS
@@ -1,4 +1,5 @@ dcheng@chromium.org +huangdarwin@chromium.org # TEAM: storage-dev@chromium.org # COMPONENT: Blink>DataTransfer
diff --git a/ui/events/blink/prediction/kalman_predictor.cc b/ui/events/blink/prediction/kalman_predictor.cc index f525ec6..dd3ff766 100644 --- a/ui/events/blink/prediction/kalman_predictor.cc +++ b/ui/events/blink/prediction/kalman_predictor.cc
@@ -22,15 +22,12 @@ constexpr base::TimeDelta InputPredictor::kTimeInterval; constexpr base::TimeDelta InputPredictor::kMinimumTimeInterval; -KalmanPredictor::KalmanPredictor(const bool enable_time_filtering) - : enable_time_filtering_(enable_time_filtering) {} +KalmanPredictor::KalmanPredictor() = default; KalmanPredictor::~KalmanPredictor() = default; const char* KalmanPredictor::GetName() const { - return enable_time_filtering_ - ? input_prediction::kScrollPredictorNameKalmanTimeFiltered - : input_prediction::kScrollPredictorNameKalman; + return input_prediction::kScrollPredictorNameKalman; } void KalmanPredictor::Reset() { @@ -47,12 +44,11 @@ dt = cur_input.time_stamp - last_point_.time_stamp; if (dt > kMaxTimeDelta) Reset(); - else if (enable_time_filtering_) + else time_filter_.Update(dt.InMillisecondsF(), 0); } - double dt_ms = enable_time_filtering_ ? time_filter_.GetPosition() - : dt.InMillisecondsF(); + double dt_ms = time_filter_.GetPosition(); last_point_ = cur_input; x_predictor_.Update(cur_input.pos.x(), dt_ms); y_predictor_.Update(cur_input.pos.y(), dt_ms);
diff --git a/ui/events/blink/prediction/kalman_predictor.h b/ui/events/blink/prediction/kalman_predictor.h index 4ba1c8b..1acfe0f 100644 --- a/ui/events/blink/prediction/kalman_predictor.h +++ b/ui/events/blink/prediction/kalman_predictor.h
@@ -19,7 +19,7 @@ // be used to predict one dimension (x, y). class KalmanPredictor : public InputPredictor { public: - explicit KalmanPredictor(bool enable_time_filtering); + explicit KalmanPredictor(); ~KalmanPredictor() override; const char* GetName() const override; @@ -53,7 +53,6 @@ // Filter to smooth time intervals. KalmanFilter time_filter_; - bool enable_time_filtering_; // The last input point. InputData last_point_;
diff --git a/ui/events/blink/prediction/kalman_predictor_unittest.cc b/ui/events/blink/prediction/kalman_predictor_unittest.cc index edaeda86..98a51a1f 100644 --- a/ui/events/blink/prediction/kalman_predictor_unittest.cc +++ b/ui/events/blink/prediction/kalman_predictor_unittest.cc
@@ -44,8 +44,7 @@ explicit KalmanPredictorTest() {} void SetUp() override { - predictor_ = std::make_unique<ui::KalmanPredictor>( - false /* enable_time_filtering */); + predictor_ = std::make_unique<ui::KalmanPredictor>(); } DISALLOW_COPY_AND_ASSIGN(KalmanPredictorTest); @@ -90,50 +89,35 @@ ValidatePredictor(x, y, t); } -// Tests the kalman predictor constant position with time filtering. -TEST_F(KalmanPredictorTest, PredictConstantValueTimeFiltered) { - predictor_ = - std::make_unique<ui::KalmanPredictor>(true /* enable_time_filtering */); - std::vector<double> x = {50, 50, 50, 50, 50, 50}; - std::vector<double> y = {-50, -50, -50, -50, -50, -50}; - std::vector<double> t = {8, 16, 24, 32, 40, 48}; - ValidatePredictor(x, y, t); -} - // Tests the kalman predictor predict constant velocity. TEST_F(KalmanPredictorTest, PredictLinearValue) { - std::vector<double> x = {0, 8, 16, 20, 23, 27, 31, 38, 48, 60}; - std::vector<double> y = {30, 38, 46, 50, 53, 57, 61, 68, 78, 90}; - std::vector<double> t = {0, 8, 16, 20, 23, 27, 31, 38, 48, 60}; - ValidatePredictor(x, y, t); -} + // The kalman filter is initialized with a velocity of zero. The change of + // velocity from zero to the constant value will be attributed to + // acceleration. Given how the filter works, it will take a few updates for it + // to get accustomed to a constant velocity. + std::vector<double> x_stabilizer = {-40, -32, -24, -16, -8}; + std::vector<double> y_stabilizer = {-10, -2, 6, 14, 22}; + std::vector<double> t_stabilizer = {-40, -32, -24, -16, -8}; + for (size_t i = 0; i < t_stabilizer.size(); i++) { + InputPredictor::InputData data = { + gfx::PointF(x_stabilizer[i], y_stabilizer[i]), + FromMilliseconds(t_stabilizer[i])}; + predictor_->Update(data); + } -// Tests the time filtering as the kalman predictor predicts constant velocity. -// Position is changing on a fixed rate assuming a fixed hardware resample -// frequency. Due to timestamp noise generated by the OS event delivery, -// timestamps are inconsistent. -TEST_F(KalmanPredictorTest, PredictLinearValueTimeFiltered) { - std::unique_ptr<ui::KalmanPredictor> filtered_predictor = - std::make_unique<ui::KalmanPredictor>(true /* enable_time_filtering */); std::vector<double> x = {0, 8, 16, 24, 32, 40, 48, 60}; std::vector<double> y = {30, 38, 46, 54, 62, 70, 78, 90}; - std::vector<double> t = {0, 8, 16, 23, 33, 39, 49, 60}; + std::vector<double> t = {0, 8, 16, 24, 32, 40, 48, 60}; for (size_t i = 0; i < t.size(); i++) { - if (filtered_predictor->HasPrediction() && predictor_->HasPrediction()) { - ui::InputPredictor::InputData filtered_result; - ui::InputPredictor::InputData unfiltered_result; - EXPECT_TRUE(filtered_predictor->GeneratePrediction(FromMilliseconds(t[i]), - &filtered_result)); - EXPECT_TRUE(predictor_->GeneratePrediction(FromMilliseconds(t[i]), - &unfiltered_result)); - EXPECT_LT(std::abs(filtered_result.pos.x() - x[i]), - std::abs(unfiltered_result.pos.x() - x[i])); - EXPECT_LT(std::abs(filtered_result.pos.y() - y[i]), - std::abs(unfiltered_result.pos.y() - y[i])); + if (predictor_->HasPrediction()) { + ui::InputPredictor::InputData result; + EXPECT_TRUE( + predictor_->GeneratePrediction(FromMilliseconds(t[i]), &result)); + EXPECT_NEAR(result.pos.x(), x[i], kEpsilon); + EXPECT_NEAR(result.pos.y(), y[i], kEpsilon); } InputPredictor::InputData data = {gfx::PointF(x[i], y[i]), FromMilliseconds(t[i])}; - filtered_predictor->Update(data); predictor_->Update(data); } } @@ -146,20 +130,9 @@ ValidatePredictor(x, y, t); } -// Tests the kalman predictor predict constant acceleration with time filtering. -TEST_F(KalmanPredictorTest, PredictQuadraticValueTimeFiltered) { - predictor_ = - std::make_unique<ui::KalmanPredictor>(true /* enable_time_filtering */); - std::vector<double> x = {0, 2, 8, 18, 32, 50, 72, 98}; - std::vector<double> y = {10, 11, 14, 19, 26, 35, 46, 59}; - std::vector<double> t = {8, 16, 24, 32, 40, 48, 56, 64}; - ValidatePredictor(x, y, t); -} - // Tests the kalman predictor time interval filter. TEST_F(KalmanPredictorTest, TimeInterval) { - predictor_ = - std::make_unique<ui::KalmanPredictor>(true /* enable_time_filtering */); + predictor_ = std::make_unique<ui::KalmanPredictor>(); EXPECT_EQ(predictor_->TimeInterval(), kExpectedDefaultTimeInterval); std::vector<double> x = {0, 2, 8, 18}; std::vector<double> y = {10, 11, 14, 19};
diff --git a/ui/events/blink/prediction/predictor_factory.cc b/ui/events/blink/prediction/predictor_factory.cc index b0f617c..f971870 100644 --- a/ui/events/blink/prediction/predictor_factory.cc +++ b/ui/events/blink/prediction/predictor_factory.cc
@@ -15,7 +15,6 @@ const char kScrollPredictorNameLsq[] = "lsq"; const char kScrollPredictorNameKalman[] = "kalman"; -const char kScrollPredictorNameKalmanTimeFiltered[] = "kalman_time_filtered"; const char kScrollPredictorNameLinearFirst[] = "linear_first"; const char kScrollPredictorNameLinearSecond[] = "linear_second"; const char kScrollPredictorNameEmpty[] = "empty"; @@ -32,9 +31,6 @@ return PredictorType::kScrollPredictorTypeLsq; else if (predictor_name == input_prediction::kScrollPredictorNameKalman) return PredictorType::kScrollPredictorTypeKalman; - else if (predictor_name == - input_prediction::kScrollPredictorNameKalmanTimeFiltered) - return PredictorType::kScrollPredictorTypeKalmanTimeFiltered; else if (predictor_name == input_prediction::kScrollPredictorNameLinearFirst) return PredictorType::kScrollPredictorTypeLinearFirst; else if (predictor_name == input_prediction::kScrollPredictorNameLinearSecond) @@ -48,10 +44,7 @@ if (predictor_type == PredictorType::kScrollPredictorTypeLsq) return std::make_unique<LeastSquaresPredictor>(); else if (predictor_type == PredictorType::kScrollPredictorTypeKalman) - return std::make_unique<KalmanPredictor>(false /* enable_time_filtering */); - else if (predictor_type == - PredictorType::kScrollPredictorTypeKalmanTimeFiltered) - return std::make_unique<KalmanPredictor>(true /* enable_time_filtering */); + return std::make_unique<KalmanPredictor>(); else if (predictor_type == PredictorType::kScrollPredictorTypeLinearFirst) return std::make_unique<LinearPredictor>( LinearPredictor::EquationOrder::kFirstOrder);
diff --git a/ui/events/blink/prediction/predictor_factory.h b/ui/events/blink/prediction/predictor_factory.h index 1d21781..7488cfa 100644 --- a/ui/events/blink/prediction/predictor_factory.h +++ b/ui/events/blink/prediction/predictor_factory.h
@@ -13,7 +13,6 @@ extern const char kScrollPredictorNameLsq[]; extern const char kScrollPredictorNameKalman[]; -extern const char kScrollPredictorNameKalmanTimeFiltered[]; extern const char kScrollPredictorNameLinearFirst[]; extern const char kScrollPredictorNameLinearSecond[]; extern const char kScrollPredictorNameEmpty[]; @@ -21,7 +20,6 @@ enum class PredictorType { kScrollPredictorTypeLsq, kScrollPredictorTypeKalman, - kScrollPredictorTypeKalmanTimeFiltered, kScrollPredictorTypeLinearFirst, kScrollPredictorTypeLinearSecond, kScrollPredictorTypeEmpty
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 7c442a51..d15c1c1 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -247,6 +247,10 @@ 'versions': [{ 'name': 'glClientWaitSync', 'extensions': ['GL_ARB_sync'] }], 'arguments': 'GLsync sync, GLbitfield flags, GLuint64 timeout', }, +{ 'return_type': 'GLenum', + 'versions': [{ 'name': 'glClientWaitSyncAPPLE', + 'extensions': ['GL_APPLE_sync'] }], + 'arguments': 'GLsync sync, GLbitfield flags, GLuint64 timeout', }, { 'return_type': 'void', 'names': ['glColorMask'], 'arguments': @@ -467,6 +471,10 @@ 'extensions': ['GL_ARB_sync'] }], 'arguments': 'GLsync sync', }, { 'return_type': 'void', + 'versions': [{ 'name': 'glDeleteSyncAPPLE', + 'extensions': ['GL_APPLE_sync'] }], + 'arguments': 'GLsync sync', }, +{ 'return_type': 'void', 'names': ['glDeleteTextures'], 'arguments': 'GLsizei n, const GLuint* textures', }, { 'return_type': 'void', @@ -576,6 +584,10 @@ 'versions': [{ 'name': 'glFenceSync', 'extensions': ['GL_ARB_sync'] }], 'arguments': 'GLenum condition, GLbitfield flags', }, +{ 'return_type': 'GLsync', + 'versions': [{ 'name': 'glFenceSyncAPPLE', + 'extensions': ['GL_APPLE_sync'] }], + 'arguments': 'GLenum condition, GLbitfield flags', }, { 'return_type': 'void', 'names': ['glFinish'], 'arguments': 'void', }, @@ -1321,6 +1333,10 @@ 'extensions': ['GL_ARB_sync'] }], 'arguments': 'GLsync sync', }, { 'return_type': 'GLboolean', + 'versions': [{ 'name': 'glIsSyncAPPLE', + 'extensions': ['GL_APPLE_sync'] }], + 'arguments': 'GLsync sync', }, +{ 'return_type': 'GLboolean', 'names': ['glIsTexture'], 'arguments': 'GLuint texture', }, { 'return_type': 'GLboolean', @@ -2203,6 +2219,11 @@ 'arguments': 'GLsync sync, GLbitfield flags, GLuint64 timeout', }, { 'return_type': 'void', + 'versions': [{ 'name': 'glWaitSyncAPPLE', + 'extensions': ['GL_APPLE_sync'] }], + 'arguments': + 'GLsync sync, GLbitfield flags, GLuint64 timeout', }, +{ 'return_type': 'void', 'names': ['glWindowRectanglesEXT'], 'arguments': 'GLenum mode, GLsizei n, const GLint* box', }, ] @@ -3416,7 +3437,7 @@ 'GLsizei': '0', 'GLfloat': '0.0f', 'GLdouble': '0.0', - 'GLsync': 'NULL', + 'GLsync': 'nullptr', 'GLDEBUGPROC': 'NULL'} if return_type.endswith('*'): file.write(' return NULL;\n')
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index 4209b0c7..a0cb30d7 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -130,6 +130,9 @@ GLenum glClientWaitSyncFn(GLsync sync, GLbitfield flags, GLuint64 timeout) override; +GLenum glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) override; void glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -319,6 +322,7 @@ void glDeleteSemaphoresEXTFn(GLsizei n, const GLuint* semaphores) override; void glDeleteShaderFn(GLuint shader) override; void glDeleteSyncFn(GLsync sync) override; +void glDeleteSyncAPPLEFn(GLsync sync) override; void glDeleteTexturesFn(GLsizei n, const GLuint* textures) override; void glDeleteTransformFeedbacksFn(GLsizei n, const GLuint* ids) override; void glDeleteVertexArraysOESFn(GLsizei n, const GLuint* arrays) override; @@ -371,6 +375,7 @@ void glEndQueryFn(GLenum target) override; void glEndTransformFeedbackFn(void) override; GLsync glFenceSyncFn(GLenum condition, GLbitfield flags) override; +GLsync glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) override; void glFinishFn(void) override; void glFinishFenceAPPLEFn(GLuint fence) override; void glFinishFenceNVFn(GLuint fence) override; @@ -888,6 +893,7 @@ GLboolean glIsSamplerFn(GLuint sampler) override; GLboolean glIsShaderFn(GLuint shader) override; GLboolean glIsSyncFn(GLsync sync) override; +GLboolean glIsSyncAPPLEFn(GLsync sync) override; GLboolean glIsTextureFn(GLuint texture) override; GLboolean glIsTransformFeedbackFn(GLuint id) override; GLboolean glIsVertexArrayOESFn(GLuint array) override; @@ -1547,4 +1553,7 @@ const GLuint* textures, const GLenum* srcLayouts) override; void glWaitSyncFn(GLsync sync, GLbitfield flags, GLuint64 timeout) override; +void glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) override; void glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) override;
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index 1383f590..7849e73 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -298,6 +298,7 @@ ext.b_GL_ANGLE_translated_shader_source = gfx::HasExtension(extensions, "GL_ANGLE_translated_shader_source"); ext.b_GL_APPLE_fence = gfx::HasExtension(extensions, "GL_APPLE_fence"); + ext.b_GL_APPLE_sync = gfx::HasExtension(extensions, "GL_APPLE_sync"); ext.b_GL_APPLE_vertex_array_object = gfx::HasExtension(extensions, "GL_APPLE_vertex_array_object"); ext.b_GL_ARB_ES2_compatibility = @@ -652,6 +653,11 @@ GetGLProcAddress("glClientWaitSync")); } + if (ext.b_GL_APPLE_sync) { + fn.glClientWaitSyncAPPLEFn = reinterpret_cast<glClientWaitSyncAPPLEProc>( + GetGLProcAddress("glClientWaitSyncAPPLE")); + } + if (ext.b_GL_ANGLE_robust_client_memory) { fn.glCompressedTexImage2DRobustANGLEFn = reinterpret_cast<glCompressedTexImage2DRobustANGLEProc>( @@ -860,6 +866,11 @@ reinterpret_cast<glDeleteSyncProc>(GetGLProcAddress("glDeleteSync")); } + if (ext.b_GL_APPLE_sync) { + fn.glDeleteSyncAPPLEFn = reinterpret_cast<glDeleteSyncAPPLEProc>( + GetGLProcAddress("glDeleteSyncAPPLE")); + } + if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u) || ext.b_GL_ARB_transform_feedback2) { fn.glDeleteTransformFeedbacksFn = @@ -1001,6 +1012,11 @@ reinterpret_cast<glFenceSyncProc>(GetGLProcAddress("glFenceSync")); } + if (ext.b_GL_APPLE_sync) { + fn.glFenceSyncAPPLEFn = reinterpret_cast<glFenceSyncAPPLEProc>( + GetGLProcAddress("glFenceSyncAPPLE")); + } + if (ext.b_GL_APPLE_fence) { fn.glFinishFenceAPPLEFn = reinterpret_cast<glFinishFenceAPPLEProc>( GetGLProcAddress("glFinishFenceAPPLE")); @@ -1855,6 +1871,11 @@ reinterpret_cast<glIsSyncProc>(GetGLProcAddress("glIsSync")); } + if (ext.b_GL_APPLE_sync) { + fn.glIsSyncAPPLEFn = + reinterpret_cast<glIsSyncAPPLEProc>(GetGLProcAddress("glIsSyncAPPLE")); + } + if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u) || ext.b_GL_ARB_transform_feedback2) { fn.glIsTransformFeedbackFn = reinterpret_cast<glIsTransformFeedbackProc>( @@ -2788,6 +2809,11 @@ reinterpret_cast<glWaitSyncProc>(GetGLProcAddress("glWaitSync")); } + if (ext.b_GL_APPLE_sync) { + fn.glWaitSyncAPPLEFn = reinterpret_cast<glWaitSyncAPPLEProc>( + GetGLProcAddress("glWaitSyncAPPLE")); + } + if (ext.b_GL_EXT_window_rectangles) { fn.glWindowRectanglesEXTFn = reinterpret_cast<glWindowRectanglesEXTProc>( GetGLProcAddress("glWindowRectanglesEXT")); @@ -3055,6 +3081,12 @@ return driver_->fn.glClientWaitSyncFn(sync, flags, timeout); } +GLenum GLApiBase::glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + return driver_->fn.glClientWaitSyncAPPLEFn(sync, flags, timeout); +} + void GLApiBase::glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -3398,6 +3430,10 @@ driver_->fn.glDeleteSyncFn(sync); } +void GLApiBase::glDeleteSyncAPPLEFn(GLsync sync) { + driver_->fn.glDeleteSyncAPPLEFn(sync); +} + void GLApiBase::glDeleteTexturesFn(GLsizei n, const GLuint* textures) { driver_->fn.glDeleteTexturesFn(n, textures); } @@ -3538,6 +3574,10 @@ return driver_->fn.glFenceSyncFn(condition, flags); } +GLsync GLApiBase::glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) { + return driver_->fn.glFenceSyncAPPLEFn(condition, flags); +} + void GLApiBase::glFinishFn(void) { driver_->fn.glFinishFn(); } @@ -4622,6 +4662,10 @@ return driver_->fn.glIsSyncFn(sync); } +GLboolean GLApiBase::glIsSyncAPPLEFn(GLsync sync) { + return driver_->fn.glIsSyncAPPLEFn(sync); +} + GLboolean GLApiBase::glIsTextureFn(GLuint texture) { return driver_->fn.glIsTextureFn(texture); } @@ -5970,6 +6014,12 @@ driver_->fn.glWaitSyncFn(sync, flags, timeout); } +void GLApiBase::glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + driver_->fn.glWaitSyncAPPLEFn(sync, flags, timeout); +} + void GLApiBase::glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) { @@ -6284,6 +6334,13 @@ return gl_api_->glClientWaitSyncFn(sync, flags, timeout); } +GLenum TraceGLApi::glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glClientWaitSyncAPPLE") + return gl_api_->glClientWaitSyncAPPLEFn(sync, flags, timeout); +} + void TraceGLApi::glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -6675,6 +6732,11 @@ gl_api_->glDeleteSyncFn(sync); } +void TraceGLApi::glDeleteSyncAPPLEFn(GLsync sync) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glDeleteSyncAPPLE") + gl_api_->glDeleteSyncAPPLEFn(sync); +} + void TraceGLApi::glDeleteTexturesFn(GLsizei n, const GLuint* textures) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glDeleteTextures") gl_api_->glDeleteTexturesFn(n, textures); @@ -6847,6 +6909,11 @@ return gl_api_->glFenceSyncFn(condition, flags); } +GLsync TraceGLApi::glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glFenceSyncAPPLE") + return gl_api_->glFenceSyncAPPLEFn(condition, flags); +} + void TraceGLApi::glFinishFn(void) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glFinish") gl_api_->glFinishFn(); @@ -8129,6 +8196,11 @@ return gl_api_->glIsSyncFn(sync); } +GLboolean TraceGLApi::glIsSyncAPPLEFn(GLsync sync) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glIsSyncAPPLE") + return gl_api_->glIsSyncAPPLEFn(sync); +} + GLboolean TraceGLApi::glIsTextureFn(GLuint texture) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glIsTexture") return gl_api_->glIsTextureFn(texture); @@ -9704,6 +9776,13 @@ gl_api_->glWaitSyncFn(sync, flags, timeout); } +void TraceGLApi::glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glWaitSyncAPPLE") + gl_api_->glWaitSyncAPPLEFn(sync, flags, timeout); +} + void TraceGLApi::glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) { @@ -10104,6 +10183,16 @@ return result; } +GLenum DebugGLApi::glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + GL_SERVICE_LOG("glClientWaitSyncAPPLE" + << "(" << sync << ", " << flags << ", " << timeout << ")"); + GLenum result = gl_api_->glClientWaitSyncAPPLEFn(sync, flags, timeout); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; +} + void DebugGLApi::glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -10624,6 +10713,12 @@ gl_api_->glDeleteSyncFn(sync); } +void DebugGLApi::glDeleteSyncAPPLEFn(GLsync sync) { + GL_SERVICE_LOG("glDeleteSyncAPPLE" + << "(" << sync << ")"); + gl_api_->glDeleteSyncAPPLEFn(sync); +} + void DebugGLApi::glDeleteTexturesFn(GLsizei n, const GLuint* textures) { GL_SERVICE_LOG("glDeleteTextures" << "(" << n << ", " << static_cast<const void*>(textures) @@ -10845,6 +10940,15 @@ return result; } +GLsync DebugGLApi::glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) { + GL_SERVICE_LOG("glFenceSyncAPPLE" + << "(" << GLEnums::GetStringEnum(condition) << ", " << flags + << ")"); + GLsync result = gl_api_->glFenceSyncAPPLEFn(condition, flags); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; +} + void DebugGLApi::glFinishFn(void) { GL_SERVICE_LOG("glFinish" << "(" @@ -12564,6 +12668,14 @@ return result; } +GLboolean DebugGLApi::glIsSyncAPPLEFn(GLsync sync) { + GL_SERVICE_LOG("glIsSyncAPPLE" + << "(" << sync << ")"); + GLboolean result = gl_api_->glIsSyncAPPLEFn(sync); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; +} + GLboolean DebugGLApi::glIsTextureFn(GLuint texture) { GL_SERVICE_LOG("glIsTexture" << "(" << texture << ")"); @@ -14628,6 +14740,14 @@ gl_api_->glWaitSyncFn(sync, flags, timeout); } +void DebugGLApi::glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + GL_SERVICE_LOG("glWaitSyncAPPLE" + << "(" << sync << ", " << flags << ", " << timeout << ")"); + gl_api_->glWaitSyncAPPLEFn(sync, flags, timeout); +} + void DebugGLApi::glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) { @@ -14905,6 +15025,13 @@ return static_cast<GLenum>(0); } +GLenum NoContextGLApi::glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + NoContextHelper("glClientWaitSyncAPPLE"); + return static_cast<GLenum>(0); +} + void NoContextGLApi::glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -15230,6 +15357,10 @@ NoContextHelper("glDeleteSync"); } +void NoContextGLApi::glDeleteSyncAPPLEFn(GLsync sync) { + NoContextHelper("glDeleteSyncAPPLE"); +} + void NoContextGLApi::glDeleteTexturesFn(GLsizei n, const GLuint* textures) { NoContextHelper("glDeleteTextures"); } @@ -15370,7 +15501,12 @@ GLsync NoContextGLApi::glFenceSyncFn(GLenum condition, GLbitfield flags) { NoContextHelper("glFenceSync"); - return NULL; + return nullptr; +} + +GLsync NoContextGLApi::glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) { + NoContextHelper("glFenceSyncAPPLE"); + return nullptr; } void NoContextGLApi::glFinishFn(void) { @@ -16438,6 +16574,11 @@ return GL_FALSE; } +GLboolean NoContextGLApi::glIsSyncAPPLEFn(GLsync sync) { + NoContextHelper("glIsSyncAPPLE"); + return GL_FALSE; +} + GLboolean NoContextGLApi::glIsTextureFn(GLuint texture) { NoContextHelper("glIsTexture"); return GL_FALSE; @@ -17779,6 +17920,12 @@ NoContextHelper("glWaitSync"); } +void NoContextGLApi::glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + NoContextHelper("glWaitSyncAPPLE"); +} + void NoContextGLApi::glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) {
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index a946928..4151b91 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -147,6 +147,9 @@ typedef GLenum(GL_BINDING_CALL* glClientWaitSyncProc)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef GLenum(GL_BINDING_CALL* glClientWaitSyncAPPLEProc)(GLsync sync, + GLbitfield flags, + GLuint64 timeout); typedef void(GL_BINDING_CALL* glColorMaskProc)(GLboolean red, GLboolean green, GLboolean blue, @@ -362,6 +365,7 @@ const GLuint* semaphores); typedef void(GL_BINDING_CALL* glDeleteShaderProc)(GLuint shader); typedef void(GL_BINDING_CALL* glDeleteSyncProc)(GLsync sync); +typedef void(GL_BINDING_CALL* glDeleteSyncAPPLEProc)(GLsync sync); typedef void(GL_BINDING_CALL* glDeleteTexturesProc)(GLsizei n, const GLuint* textures); typedef void(GL_BINDING_CALL* glDeleteTransformFeedbacksProc)( @@ -430,6 +434,8 @@ typedef void(GL_BINDING_CALL* glEndTransformFeedbackProc)(void); typedef GLsync(GL_BINDING_CALL* glFenceSyncProc)(GLenum condition, GLbitfield flags); +typedef GLsync(GL_BINDING_CALL* glFenceSyncAPPLEProc)(GLenum condition, + GLbitfield flags); typedef void(GL_BINDING_CALL* glFinishProc)(void); typedef void(GL_BINDING_CALL* glFinishFenceAPPLEProc)(GLuint fence); typedef void(GL_BINDING_CALL* glFinishFenceNVProc)(GLuint fence); @@ -1046,6 +1052,7 @@ typedef GLboolean(GL_BINDING_CALL* glIsSamplerProc)(GLuint sampler); typedef GLboolean(GL_BINDING_CALL* glIsShaderProc)(GLuint shader); typedef GLboolean(GL_BINDING_CALL* glIsSyncProc)(GLsync sync); +typedef GLboolean(GL_BINDING_CALL* glIsSyncAPPLEProc)(GLsync sync); typedef GLboolean(GL_BINDING_CALL* glIsTextureProc)(GLuint texture); typedef GLboolean(GL_BINDING_CALL* glIsTransformFeedbackProc)(GLuint id); typedef GLboolean(GL_BINDING_CALL* glIsVertexArrayOESProc)(GLuint array); @@ -1840,6 +1847,9 @@ typedef void(GL_BINDING_CALL* glWaitSyncProc)(GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void(GL_BINDING_CALL* glWaitSyncAPPLEProc)(GLsync sync, + GLbitfield flags, + GLuint64 timeout); typedef void(GL_BINDING_CALL* glWindowRectanglesEXTProc)(GLenum mode, GLsizei n, const GLint* box); @@ -1855,6 +1865,7 @@ bool b_GL_ANGLE_texture_external_update; bool b_GL_ANGLE_translated_shader_source; bool b_GL_APPLE_fence; + bool b_GL_APPLE_sync; bool b_GL_APPLE_vertex_array_object; bool b_GL_ARB_ES2_compatibility; bool b_GL_ARB_blend_func_extended; @@ -1978,6 +1989,7 @@ glClearTexImageProc glClearTexImageFn; glClearTexSubImageProc glClearTexSubImageFn; glClientWaitSyncProc glClientWaitSyncFn; + glClientWaitSyncAPPLEProc glClientWaitSyncAPPLEFn; glColorMaskProc glColorMaskFn; glCompileShaderProc glCompileShaderFn; glCompressedTexImage2DProc glCompressedTexImage2DFn; @@ -2022,6 +2034,7 @@ glDeleteSemaphoresEXTProc glDeleteSemaphoresEXTFn; glDeleteShaderProc glDeleteShaderFn; glDeleteSyncProc glDeleteSyncFn; + glDeleteSyncAPPLEProc glDeleteSyncAPPLEFn; glDeleteTexturesProc glDeleteTexturesFn; glDeleteTransformFeedbacksProc glDeleteTransformFeedbacksFn; glDeleteVertexArraysOESProc glDeleteVertexArraysOESFn; @@ -2052,6 +2065,7 @@ glEndQueryProc glEndQueryFn; glEndTransformFeedbackProc glEndTransformFeedbackFn; glFenceSyncProc glFenceSyncFn; + glFenceSyncAPPLEProc glFenceSyncAPPLEFn; glFinishProc glFinishFn; glFinishFenceAPPLEProc glFinishFenceAPPLEFn; glFinishFenceNVProc glFinishFenceNVFn; @@ -2221,6 +2235,7 @@ glIsSamplerProc glIsSamplerFn; glIsShaderProc glIsShaderFn; glIsSyncProc glIsSyncFn; + glIsSyncAPPLEProc glIsSyncAPPLEFn; glIsTextureProc glIsTextureFn; glIsTransformFeedbackProc glIsTransformFeedbackFn; glIsVertexArrayOESProc glIsVertexArrayOESFn; @@ -2422,6 +2437,7 @@ glViewportProc glViewportFn; glWaitSemaphoreEXTProc glWaitSemaphoreEXTFn; glWaitSyncProc glWaitSyncFn; + glWaitSyncAPPLEProc glWaitSyncAPPLEFn; glWindowRectanglesEXTProc glWindowRectanglesEXTFn; }; @@ -2552,6 +2568,9 @@ virtual GLenum glClientWaitSyncFn(GLsync sync, GLbitfield flags, GLuint64 timeout) = 0; + virtual GLenum glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) = 0; virtual void glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -2744,6 +2763,7 @@ virtual void glDeleteSemaphoresEXTFn(GLsizei n, const GLuint* semaphores) = 0; virtual void glDeleteShaderFn(GLuint shader) = 0; virtual void glDeleteSyncFn(GLsync sync) = 0; + virtual void glDeleteSyncAPPLEFn(GLsync sync) = 0; virtual void glDeleteTexturesFn(GLsizei n, const GLuint* textures) = 0; virtual void glDeleteTransformFeedbacksFn(GLsizei n, const GLuint* ids) = 0; virtual void glDeleteVertexArraysOESFn(GLsizei n, const GLuint* arrays) = 0; @@ -2797,6 +2817,7 @@ virtual void glEndQueryFn(GLenum target) = 0; virtual void glEndTransformFeedbackFn(void) = 0; virtual GLsync glFenceSyncFn(GLenum condition, GLbitfield flags) = 0; + virtual GLsync glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) = 0; virtual void glFinishFn(void) = 0; virtual void glFinishFenceAPPLEFn(GLuint fence) = 0; virtual void glFinishFenceNVFn(GLuint fence) = 0; @@ -3337,6 +3358,7 @@ virtual GLboolean glIsSamplerFn(GLuint sampler) = 0; virtual GLboolean glIsShaderFn(GLuint shader) = 0; virtual GLboolean glIsSyncFn(GLsync sync) = 0; + virtual GLboolean glIsSyncAPPLEFn(GLsync sync) = 0; virtual GLboolean glIsTextureFn(GLuint texture) = 0; virtual GLboolean glIsTransformFeedbackFn(GLuint id) = 0; virtual GLboolean glIsVertexArrayOESFn(GLuint array) = 0; @@ -4062,6 +4084,9 @@ virtual void glWaitSyncFn(GLsync sync, GLbitfield flags, GLuint64 timeout) = 0; + virtual void glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) = 0; virtual void glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) = 0; @@ -4127,6 +4152,8 @@ #define glClearTexImage ::gl::g_current_gl_context->glClearTexImageFn #define glClearTexSubImage ::gl::g_current_gl_context->glClearTexSubImageFn #define glClientWaitSync ::gl::g_current_gl_context->glClientWaitSyncFn +#define glClientWaitSyncAPPLE \ + ::gl::g_current_gl_context->glClientWaitSyncAPPLEFn #define glColorMask ::gl::g_current_gl_context->glColorMaskFn #define glCompileShader ::gl::g_current_gl_context->glCompileShaderFn #define glCompressedTexImage2D \ @@ -4190,6 +4217,7 @@ ::gl::g_current_gl_context->glDeleteSemaphoresEXTFn #define glDeleteShader ::gl::g_current_gl_context->glDeleteShaderFn #define glDeleteSync ::gl::g_current_gl_context->glDeleteSyncFn +#define glDeleteSyncAPPLE ::gl::g_current_gl_context->glDeleteSyncAPPLEFn #define glDeleteTextures ::gl::g_current_gl_context->glDeleteTexturesFn #define glDeleteTransformFeedbacks \ ::gl::g_current_gl_context->glDeleteTransformFeedbacksFn @@ -4231,6 +4259,7 @@ #define glEndTransformFeedback \ ::gl::g_current_gl_context->glEndTransformFeedbackFn #define glFenceSync ::gl::g_current_gl_context->glFenceSyncFn +#define glFenceSyncAPPLE ::gl::g_current_gl_context->glFenceSyncAPPLEFn #define glFinish ::gl::g_current_gl_context->glFinishFn #define glFinishFenceAPPLE ::gl::g_current_gl_context->glFinishFenceAPPLEFn #define glFinishFenceNV ::gl::g_current_gl_context->glFinishFenceNVFn @@ -4481,6 +4510,7 @@ #define glIsSampler ::gl::g_current_gl_context->glIsSamplerFn #define glIsShader ::gl::g_current_gl_context->glIsShaderFn #define glIsSync ::gl::g_current_gl_context->glIsSyncFn +#define glIsSyncAPPLE ::gl::g_current_gl_context->glIsSyncAPPLEFn #define glIsTexture ::gl::g_current_gl_context->glIsTextureFn #define glIsTransformFeedback \ ::gl::g_current_gl_context->glIsTransformFeedbackFn @@ -4740,6 +4770,7 @@ #define glViewport ::gl::g_current_gl_context->glViewportFn #define glWaitSemaphoreEXT ::gl::g_current_gl_context->glWaitSemaphoreEXTFn #define glWaitSync ::gl::g_current_gl_context->glWaitSyncFn +#define glWaitSyncAPPLE ::gl::g_current_gl_context->glWaitSyncAPPLEFn #define glWindowRectanglesEXT \ ::gl::g_current_gl_context->glWindowRectanglesEXTFn
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index a123fe0..483d0a8 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -511,6 +511,14 @@ return interface_->ClientWaitSync(sync, flags, timeout); } +GLenum GL_BINDING_CALL +MockGLInterface::Mock_glClientWaitSyncAPPLE(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + MakeGlMockFunctionUnique("glClientWaitSyncAPPLE"); + return interface_->ClientWaitSyncAPPLE(sync, flags, timeout); +} + void GL_BINDING_CALL MockGLInterface::Mock_glColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -1037,6 +1045,11 @@ interface_->DeleteSync(sync); } +void GL_BINDING_CALL MockGLInterface::Mock_glDeleteSyncAPPLE(GLsync sync) { + MakeGlMockFunctionUnique("glDeleteSyncAPPLE"); + interface_->DeleteSyncAPPLE(sync); +} + void GL_BINDING_CALL MockGLInterface::Mock_glDeleteTextures(GLsizei n, const GLuint* textures) { MakeGlMockFunctionUnique("glDeleteTextures"); @@ -1306,6 +1319,12 @@ return interface_->FenceSync(condition, flags); } +GLsync GL_BINDING_CALL +MockGLInterface::Mock_glFenceSyncAPPLE(GLenum condition, GLbitfield flags) { + MakeGlMockFunctionUnique("glFenceSyncAPPLE"); + return interface_->FenceSyncAPPLE(condition, flags); +} + void GL_BINDING_CALL MockGLInterface::Mock_glFinish(void) { MakeGlMockFunctionUnique("glFinish"); interface_->Finish(); @@ -2948,6 +2967,11 @@ return interface_->IsSync(sync); } +GLboolean GL_BINDING_CALL MockGLInterface::Mock_glIsSyncAPPLE(GLsync sync) { + MakeGlMockFunctionUnique("glIsSyncAPPLE"); + return interface_->IsSyncAPPLE(sync); +} + GLboolean GL_BINDING_CALL MockGLInterface::Mock_glIsTexture(GLuint texture) { MakeGlMockFunctionUnique("glIsTexture"); return interface_->IsTexture(texture); @@ -4990,6 +5014,13 @@ interface_->WaitSync(sync, flags, timeout); } +void GL_BINDING_CALL MockGLInterface::Mock_glWaitSyncAPPLE(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + MakeGlMockFunctionUnique("glWaitSyncAPPLE"); + interface_->WaitSyncAPPLE(sync, flags, timeout); +} + void GL_BINDING_CALL MockGLInterface::Mock_glWindowRectanglesEXT(GLenum mode, GLsizei n, @@ -5142,6 +5173,8 @@ return reinterpret_cast<GLFunctionPointerType>(Mock_glClearTexSubImageEXT); if (strcmp(name, "glClientWaitSync") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glClientWaitSync); + if (strcmp(name, "glClientWaitSyncAPPLE") == 0) + return reinterpret_cast<GLFunctionPointerType>(Mock_glClientWaitSyncAPPLE); if (strcmp(name, "glColorMask") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glColorMask); if (strcmp(name, "glCompileShader") == 0) @@ -5273,6 +5306,8 @@ return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteShader); if (strcmp(name, "glDeleteSync") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteSync); + if (strcmp(name, "glDeleteSyncAPPLE") == 0) + return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteSyncAPPLE); if (strcmp(name, "glDeleteTextures") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glDeleteTextures); if (strcmp(name, "glDeleteTransformFeedbacks") == 0) @@ -5368,6 +5403,8 @@ Mock_glEndTransformFeedbackEXT); if (strcmp(name, "glFenceSync") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glFenceSync); + if (strcmp(name, "glFenceSyncAPPLE") == 0) + return reinterpret_cast<GLFunctionPointerType>(Mock_glFenceSyncAPPLE); if (strcmp(name, "glFinish") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glFinish); if (strcmp(name, "glFinishFenceAPPLE") == 0) @@ -5852,6 +5889,8 @@ return reinterpret_cast<GLFunctionPointerType>(Mock_glIsShader); if (strcmp(name, "glIsSync") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glIsSync); + if (strcmp(name, "glIsSyncAPPLE") == 0) + return reinterpret_cast<GLFunctionPointerType>(Mock_glIsSyncAPPLE); if (strcmp(name, "glIsTexture") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glIsTexture); if (strcmp(name, "glIsTransformFeedback") == 0) @@ -6394,6 +6433,8 @@ return reinterpret_cast<GLFunctionPointerType>(Mock_glWaitSemaphoreEXT); if (strcmp(name, "glWaitSync") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glWaitSync); + if (strcmp(name, "glWaitSyncAPPLE") == 0) + return reinterpret_cast<GLFunctionPointerType>(Mock_glWaitSyncAPPLE); if (strcmp(name, "glWindowRectanglesEXT") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glWindowRectanglesEXT); return reinterpret_cast<GLFunctionPointerType>(&MockGlInvalidFunction);
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index 45a0b1bd43..db74334 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -211,6 +211,9 @@ static GLenum GL_BINDING_CALL Mock_glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); +static GLenum GL_BINDING_CALL Mock_glClientWaitSyncAPPLE(GLsync sync, + GLbitfield flags, + GLuint64 timeout); static void GL_BINDING_CALL Mock_glColorMask(GLboolean red, GLboolean green, GLboolean blue, @@ -465,6 +468,7 @@ Mock_glDeleteSemaphoresEXT(GLsizei n, const GLuint* semaphores); static void GL_BINDING_CALL Mock_glDeleteShader(GLuint shader); static void GL_BINDING_CALL Mock_glDeleteSync(GLsync sync); +static void GL_BINDING_CALL Mock_glDeleteSyncAPPLE(GLsync sync); static void GL_BINDING_CALL Mock_glDeleteTextures(GLsizei n, const GLuint* textures); static void GL_BINDING_CALL Mock_glDeleteTransformFeedbacks(GLsizei n, @@ -555,6 +559,8 @@ static void GL_BINDING_CALL Mock_glEndTransformFeedbackEXT(void); static GLsync GL_BINDING_CALL Mock_glFenceSync(GLenum condition, GLbitfield flags); +static GLsync GL_BINDING_CALL Mock_glFenceSyncAPPLE(GLenum condition, + GLbitfield flags); static void GL_BINDING_CALL Mock_glFinish(void); static void GL_BINDING_CALL Mock_glFinishFenceAPPLE(GLuint fence); static void GL_BINDING_CALL Mock_glFinishFenceNV(GLuint fence); @@ -1261,6 +1267,7 @@ static GLboolean GL_BINDING_CALL Mock_glIsSampler(GLuint sampler); static GLboolean GL_BINDING_CALL Mock_glIsShader(GLuint shader); static GLboolean GL_BINDING_CALL Mock_glIsSync(GLsync sync); +static GLboolean GL_BINDING_CALL Mock_glIsSyncAPPLE(GLsync sync); static GLboolean GL_BINDING_CALL Mock_glIsTexture(GLuint texture); static GLboolean GL_BINDING_CALL Mock_glIsTransformFeedback(GLuint id); static GLboolean GL_BINDING_CALL Mock_glIsVertexArray(GLuint array); @@ -2181,6 +2188,9 @@ static void GL_BINDING_CALL Mock_glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); +static void GL_BINDING_CALL Mock_glWaitSyncAPPLE(GLsync sync, + GLbitfield flags, + GLuint64 timeout); static void GL_BINDING_CALL Mock_glWindowRectanglesEXT(GLenum mode, GLsizei n, const GLint* box);
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index 59ef4f7b..69e6d25 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h
@@ -107,6 +107,8 @@ // glClearTexSubImage cannot be mocked because it has 11 args. MOCK_METHOD3(ClientWaitSync, GLenum(GLsync sync, GLbitfield flags, GLuint64 timeout)); +MOCK_METHOD3(ClientWaitSyncAPPLE, + GLenum(GLsync sync, GLbitfield flags, GLuint64 timeout)); MOCK_METHOD4( ColorMask, void(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)); @@ -279,6 +281,7 @@ MOCK_METHOD2(DeleteSemaphoresEXT, void(GLsizei n, const GLuint* semaphores)); MOCK_METHOD1(DeleteShader, void(GLuint shader)); MOCK_METHOD1(DeleteSync, void(GLsync sync)); +MOCK_METHOD1(DeleteSyncAPPLE, void(GLsync sync)); MOCK_METHOD2(DeleteTextures, void(GLsizei n, const GLuint* textures)); MOCK_METHOD2(DeleteTransformFeedbacks, void(GLsizei n, const GLuint* ids)); MOCK_METHOD2(DeleteVertexArraysOES, void(GLsizei n, const GLuint* arrays)); @@ -329,6 +332,7 @@ MOCK_METHOD1(EndQuery, void(GLenum target)); MOCK_METHOD0(EndTransformFeedback, void()); MOCK_METHOD2(FenceSync, GLsync(GLenum condition, GLbitfield flags)); +MOCK_METHOD2(FenceSyncAPPLE, GLsync(GLenum condition, GLbitfield flags)); MOCK_METHOD0(Finish, void()); MOCK_METHOD1(FinishFenceAPPLE, void(GLuint fence)); MOCK_METHOD1(FinishFenceNV, void(GLuint fence)); @@ -880,6 +884,7 @@ MOCK_METHOD1(IsSampler, GLboolean(GLuint sampler)); MOCK_METHOD1(IsShader, GLboolean(GLuint shader)); MOCK_METHOD1(IsSync, GLboolean(GLsync sync)); +MOCK_METHOD1(IsSyncAPPLE, GLboolean(GLsync sync)); MOCK_METHOD1(IsTexture, GLboolean(GLuint texture)); MOCK_METHOD1(IsTransformFeedback, GLboolean(GLuint id)); MOCK_METHOD1(IsVertexArrayOES, GLboolean(GLuint array)); @@ -1490,5 +1495,7 @@ const GLuint* textures, const GLenum* srcLayouts)); MOCK_METHOD3(WaitSync, void(GLsync sync, GLbitfield flags, GLuint64 timeout)); +MOCK_METHOD3(WaitSyncAPPLE, + void(GLsync sync, GLbitfield flags, GLuint64 timeout)); MOCK_METHOD3(WindowRectanglesEXT, void(GLenum mode, GLsizei n, const GLint* box));
diff --git a/ui/gl/gl_stub_autogen_gl.cc b/ui/gl/gl_stub_autogen_gl.cc index 33f7dff4..3fee2b3 100644 --- a/ui/gl/gl_stub_autogen_gl.cc +++ b/ui/gl/gl_stub_autogen_gl.cc
@@ -22,6 +22,12 @@ return 0; } +GLenum GLStubApiBase::glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + return 0; +} + GLuint GLStubApiBase::glCreateProgramFn() { return 0; } @@ -40,6 +46,10 @@ return 0; } +GLsync GLStubApiBase::glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) { + return 0; +} + GLuint GLStubApiBase::glGenPathsNVFn(GLsizei range) { return 0; } @@ -160,6 +170,10 @@ return 0; } +GLboolean GLStubApiBase::glIsSyncAPPLEFn(GLsync sync) { + return 0; +} + GLboolean GLStubApiBase::glIsTextureFn(GLuint texture) { return 0; }
diff --git a/ui/gl/gl_stub_autogen_gl.h b/ui/gl/gl_stub_autogen_gl.h index 5f464db..bc452de 100644 --- a/ui/gl/gl_stub_autogen_gl.h +++ b/ui/gl/gl_stub_autogen_gl.h
@@ -129,6 +129,9 @@ GLenum glClientWaitSyncFn(GLsync sync, GLbitfield flags, GLuint64 timeout) override; +GLenum glClientWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) override; void glColorMaskFn(GLboolean red, GLboolean green, GLboolean blue, @@ -319,6 +322,7 @@ void glDeleteSemaphoresEXTFn(GLsizei n, const GLuint* semaphores) override {} void glDeleteShaderFn(GLuint shader) override {} void glDeleteSyncFn(GLsync sync) override {} +void glDeleteSyncAPPLEFn(GLsync sync) override {} void glDeleteTexturesFn(GLsizei n, const GLuint* textures) override {} void glDeleteTransformFeedbacksFn(GLsizei n, const GLuint* ids) override {} void glDeleteVertexArraysOESFn(GLsizei n, const GLuint* arrays) override {} @@ -371,6 +375,7 @@ void glEndQueryFn(GLenum target) override {} void glEndTransformFeedbackFn() override {} GLsync glFenceSyncFn(GLenum condition, GLbitfield flags) override; +GLsync glFenceSyncAPPLEFn(GLenum condition, GLbitfield flags) override; void glFinishFn() override {} void glFinishFenceAPPLEFn(GLuint fence) override {} void glFinishFenceNVFn(GLuint fence) override {} @@ -897,6 +902,7 @@ GLboolean glIsSamplerFn(GLuint sampler) override; GLboolean glIsShaderFn(GLuint shader) override; GLboolean glIsSyncFn(GLsync sync) override; +GLboolean glIsSyncAPPLEFn(GLsync sync) override; GLboolean glIsTextureFn(GLuint texture) override; GLboolean glIsTransformFeedbackFn(GLuint id) override; GLboolean glIsVertexArrayOESFn(GLuint array) override; @@ -1569,6 +1575,9 @@ const GLuint* textures, const GLenum* srcLayouts) override {} void glWaitSyncFn(GLsync sync, GLbitfield flags, GLuint64 timeout) override {} +void glWaitSyncAPPLEFn(GLsync sync, + GLbitfield flags, + GLuint64 timeout) override {} void glWindowRectanglesEXTFn(GLenum mode, GLsizei n, const GLint* box) override {}
diff --git a/ui/gl/init/create_gr_gl_interface.cc b/ui/gl/init/create_gr_gl_interface.cc index 2f5ccbff..6f8bbac8 100644 --- a/ui/gl/init/create_gr_gl_interface.cc +++ b/ui/gl/init/create_gr_gl_interface.cc
@@ -11,6 +11,81 @@ namespace gl { namespace init { +// This code emulates GL fences (GL_APPLE_sync or GL_ARB_sync) via +// EGL_KHR_fence_sync extension. It's used to provide Skia ways of +// synchronization on platforms that does not have GL fences but support EGL +namespace { +struct EGLFenceData { + EGLSync sync; + EGLDisplay display; +}; + +GLsync glFenceSyncEmulateEGL(GLenum condition, GLbitfield flags) { + DCHECK(condition == GL_SYNC_GPU_COMMANDS_COMPLETE); + DCHECK(flags == 0); + + init::EGLFenceData* data = new EGLFenceData; + + data->display = eglGetCurrentDisplay(); + data->sync = eglCreateSyncKHR(data->display, EGL_SYNC_FENCE_KHR, nullptr); + + return reinterpret_cast<GLsync>(data); +} + +void glDeleteSyncEmulateEGL(GLsync sync) { + EGLFenceData* data = reinterpret_cast<EGLFenceData*>(sync); + eglDestroySyncKHR(data->display, data->sync); + delete data; +} + +GLenum glClientWaitSyncEmulateEGL(GLsync sync, + GLbitfield flags, + GLuint64 timeout) { + init::EGLFenceData* data = reinterpret_cast<init::EGLFenceData*>(sync); + + EGLint egl_flags = 0; + + if (flags & GL_SYNC_FLUSH_COMMANDS_BIT) { + egl_flags |= EGL_SYNC_FLUSH_COMMANDS_BIT; + } + EGLint result = + eglClientWaitSyncKHR(data->display, data->sync, egl_flags, timeout); + + switch (result) { + case EGL_CONDITION_SATISFIED: + return GL_CONDITION_SATISFIED; + case EGL_TIMEOUT_EXPIRED: + return GL_TIMEOUT_EXPIRED; + case EGL_FALSE: + return GL_WAIT_FAILED; + } + + NOTREACHED(); + return 0; +} + +void glWaitSyncEmulateEGL(GLsync sync, GLbitfield flags, GLuint64 timeout) { + init::EGLFenceData* data = reinterpret_cast<init::EGLFenceData*>(sync); + + DCHECK(timeout == GL_TIMEOUT_IGNORED); + DCHECK(flags == 0); + + if (!g_driver_egl.ext.b_EGL_KHR_wait_sync) { + eglClientWaitSyncKHR(data->display, data->sync, 0, EGL_FOREVER_KHR); + return; + } + + EGLint result = eglWaitSyncKHR(data->display, data->sync, 0); + DCHECK(result); +} + +GLboolean glIsSyncEmulateEGL(GLsync sync) { + NOTREACHED(); + return true; +} + +} // namespace + namespace { template <typename R, typename... Args> @@ -88,7 +163,6 @@ const char* kBlacklistExtensions[] = { "GL_APPLE_framebuffer_multisample", - "GL_APPLE_sync", "GL_ARB_ES3_1_compatibility", "GL_ARB_draw_indirect", "GL_ARB_invalidate_subdata", @@ -587,6 +661,26 @@ functions->fWaitSync = gl->glWaitSyncFn; functions->fDeleteSync = gl->glDeleteSyncFn; + if (!gl->glFenceSyncFn) { + // NOTE: Skia uses the same function pointers without APPLE suffix + if (extensions.has("GL_APPLE_sync")) { + functions->fFenceSync = gl->glFenceSyncAPPLEFn; + functions->fIsSync = gl->glIsSyncAPPLEFn; + functions->fClientWaitSync = gl->glClientWaitSyncAPPLEFn; + functions->fWaitSync = gl->glWaitSyncAPPLEFn; + functions->fDeleteSync = gl->glDeleteSyncAPPLEFn; + } else if (g_driver_egl.ext.b_EGL_KHR_fence_sync) { + // Emulate APPLE_sync via egl + extensions.add("GL_APPLE_sync"); + + functions->fFenceSync = glFenceSyncEmulateEGL; + functions->fIsSync = glIsSyncEmulateEGL; + functions->fClientWaitSync = glClientWaitSyncEmulateEGL; + functions->fWaitSync = glWaitSyncEmulateEGL; + functions->fDeleteSync = glDeleteSyncEmulateEGL; + } + } + functions->fGetInternalformativ = gl->glGetInternalformativFn; interface->fStandard = standard;
diff --git a/ui/native_theme/native_theme.cc b/ui/native_theme/native_theme.cc index 091f0b7..2370d15 100644 --- a/ui/native_theme/native_theme.cc +++ b/ui/native_theme/native_theme.cc
@@ -79,6 +79,32 @@ return CaptionStyle::FromSystemSettings(); } +const std::map<NativeTheme::SystemThemeColor, SkColor>& +NativeTheme::GetSystemColors() const { + return system_colors_; +} + +bool NativeTheme::HasDifferentSystemColors( + const std::map<NativeTheme::SystemThemeColor, SkColor>& colors) const { + return system_colors_ != colors; +} + +void NativeTheme::set_system_colors( + const std::map<NativeTheme::SystemThemeColor, SkColor>& colors) { + system_colors_ = colors; +} + +void NativeTheme::UpdateSystemColorInfo( + bool is_dark_mode, + bool is_high_contrast, + PreferredColorScheme preferred_color_scheme, + const base::flat_map<SystemThemeColor, uint32_t>& colors) { + set_use_dark_colors(is_dark_mode); + set_high_contrast(is_high_contrast); + set_preferred_color_scheme(preferred_color_scheme); + system_colors_.insert(colors.begin(), colors.end()); +} + NativeTheme::ColorSchemeNativeThemeObserver::ColorSchemeNativeThemeObserver( NativeTheme* theme_to_update) : theme_to_update_(theme_to_update) {} @@ -107,6 +133,12 @@ notify_observers = true; } + const auto& system_colors = observed_theme->GetSystemColors(); + if (theme_to_update_->HasDifferentSystemColors(system_colors)) { + theme_to_update_->set_system_colors(system_colors); + notify_observers = true; + } + if (notify_observers) theme_to_update_->NotifyObservers(); }
diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h index 8d2e68a0..d12315d 100644 --- a/ui/native_theme/native_theme.h +++ b/ui/native_theme/native_theme.h
@@ -5,6 +5,8 @@ #ifndef UI_NATIVE_THEME_NATIVE_THEME_H_ #define UI_NATIVE_THEME_NATIVE_THEME_H_ +#include <map> + #include "base/macros.h" #include "base/observer_list.h" #include "build/build_config.h" @@ -106,6 +108,7 @@ kNoPreference, kDark, kLight, + kMaxValue = kLight, }; // The color scheme used for painting the native controls. @@ -399,6 +402,21 @@ kColorId_NumColors, }; + enum class SystemThemeColor { + kNotSupported, + kButtonFace, + kButtonText, + kGrayText, + kHighlight, + kHighlightText, + kHotlight, + kMenuHighlight, + kScrollbar, + kWindow, + kWindowText, + kMaxValue = kWindowText, + }; + // Return a color from the system theme. virtual SkColor GetSystemColor( ColorId color_id, @@ -444,6 +462,29 @@ ColorScheme GetSystemColorScheme() const; + virtual const std::map<SystemThemeColor, SkColor>& GetSystemColors() const; + + bool HasDifferentSystemColors( + const std::map<SystemThemeColor, SkColor>& colors) const; + + void set_use_dark_colors(bool should_use_dark_colors) { + should_use_dark_colors_ = should_use_dark_colors; + } + void set_high_contrast(bool is_high_contrast) { + is_high_contrast_ = is_high_contrast; + } + void set_preferred_color_scheme(PreferredColorScheme preferred_color_scheme) { + preferred_color_scheme_ = preferred_color_scheme; + } + + void set_system_colors(const std::map<SystemThemeColor, SkColor>& colors); + + void UpdateSystemColorInfo( + bool is_dark_mode, + bool is_high_contrast, + PreferredColorScheme preferred_color_scheme, + const base::flat_map<SystemThemeColor, uint32_t>& colors); + protected: NativeTheme(); virtual ~NativeTheme(); @@ -468,16 +509,6 @@ // be set to no-preference. virtual PreferredColorScheme CalculatePreferredColorScheme() const; - void set_use_dark_colors(bool should_use_dark_colors) { - should_use_dark_colors_ = should_use_dark_colors; - } - void set_high_contrast(bool is_high_contrast) { - is_high_contrast_ = is_high_contrast; - } - void set_preferred_color_scheme(PreferredColorScheme preferred_color_scheme) { - preferred_color_scheme_ = preferred_color_scheme; - } - // Allows one native theme to observe changes in another. For example, the // web native theme for Windows observes the corresponding ui native theme in // order to receive changes regarding the state of dark mode, high contrast, @@ -498,6 +529,8 @@ DISALLOW_COPY_AND_ASSIGN(ColorSchemeNativeThemeObserver); }; + mutable std::map<SystemThemeColor, SkColor> system_colors_; + private: // Observers to notify when the native theme changes. base::ObserverList<NativeThemeObserver>::Unchecked native_theme_observers_;
diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc index 78e3b14..2572060 100644 --- a/ui/native_theme/native_theme_win.cc +++ b/ui/native_theme/native_theme_win.cc
@@ -49,18 +49,10 @@ namespace { // Windows system color IDs cached and updated by the native theme. -const int kSystemColors[] = { - COLOR_3DFACE, - COLOR_BTNFACE, - COLOR_BTNTEXT, - COLOR_GRAYTEXT, - COLOR_HIGHLIGHT, - COLOR_HIGHLIGHTTEXT, - COLOR_HOTLIGHT, - COLOR_MENUHIGHLIGHT, - COLOR_SCROLLBAR, - COLOR_WINDOW, - COLOR_WINDOWTEXT, +const int kSysColors[] = { + COLOR_BTNFACE, COLOR_BTNTEXT, COLOR_GRAYTEXT, COLOR_HIGHLIGHT, + COLOR_HIGHLIGHTTEXT, COLOR_HOTLIGHT, COLOR_MENUHIGHLIGHT, COLOR_SCROLLBAR, + COLOR_WINDOW, COLOR_WINDOWTEXT, }; void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) { @@ -148,6 +140,33 @@ namespace ui { +NativeTheme::SystemThemeColor SysColorToSystemThemeColor(int system_color) { + switch (system_color) { + case COLOR_BTNFACE: + return NativeTheme::SystemThemeColor::kButtonFace; + case COLOR_BTNTEXT: + return NativeTheme::SystemThemeColor::kButtonText; + case COLOR_GRAYTEXT: + return NativeTheme::SystemThemeColor::kGrayText; + case COLOR_HIGHLIGHT: + return NativeTheme::SystemThemeColor::kHighlight; + case COLOR_HIGHLIGHTTEXT: + return NativeTheme::SystemThemeColor::kHighlightText; + case COLOR_HOTLIGHT: + return NativeTheme::SystemThemeColor::kHotlight; + case COLOR_MENUHIGHLIGHT: + return NativeTheme::SystemThemeColor::kMenuHighlight; + case COLOR_SCROLLBAR: + return NativeTheme::SystemThemeColor::kScrollbar; + case COLOR_WINDOW: + return NativeTheme::SystemThemeColor::kWindow; + case COLOR_WINDOWTEXT: + return NativeTheme::SystemThemeColor::kWindowText; + default: + return NativeTheme::SystemThemeColor::kNotSupported; + } +} + NativeTheme* NativeTheme::GetInstanceForNativeUi() { return NativeThemeWin::instance(); } @@ -268,6 +287,13 @@ // Initialize the cached system colors. UpdateSystemColors(); + + // Initialize the native theme web instance with the system color info. + NativeTheme* web_instance = NativeTheme::GetInstanceForWeb(); + web_instance->set_use_dark_colors(ShouldUseDarkColors()); + web_instance->set_high_contrast(UsesHighContrastColors()); + web_instance->set_preferred_color_scheme(GetPreferredColorScheme()); + web_instance->set_system_colors(GetSystemColors()); } NativeThemeWin::~NativeThemeWin() { @@ -301,8 +327,9 @@ } void NativeThemeWin::UpdateSystemColors() { - for (int kSystemColor : kSystemColors) - system_colors_[kSystemColor] = color_utils::GetSysSkColor(kSystemColor); + for (int sys_color : kSysColors) + system_colors_[SysColorToSystemThemeColor(sys_color)] = + color_utils::GetSysSkColor(sys_color); } void NativeThemeWin::PaintMenuSeparator(cc::PaintCanvas* canvas, @@ -449,7 +476,7 @@ switch (color_id) { // Windows case kColorId_WindowBackground: - return system_colors_[COLOR_WINDOW]; + return system_colors_[SystemThemeColor::kWindow]; // Dialogs case kColorId_DialogBackground: @@ -463,72 +490,74 @@ // Button case kColorId_ButtonEnabledColor: - return system_colors_[COLOR_BTNTEXT]; + return system_colors_[SystemThemeColor::kButtonText]; case kColorId_ButtonHoverColor: return kButtonHoverColor; // Label case kColorId_LabelEnabledColor: - return system_colors_[COLOR_BTNTEXT]; + return system_colors_[SystemThemeColor::kButtonText]; case kColorId_LabelDisabledColor: - return system_colors_[COLOR_GRAYTEXT]; + return system_colors_[SystemThemeColor::kGrayText]; case kColorId_LabelTextSelectionColor: - return system_colors_[COLOR_HIGHLIGHTTEXT]; + return system_colors_[SystemThemeColor::kHighlightText]; case kColorId_LabelTextSelectionBackgroundFocused: return kLabelTextSelectionBackgroundFocusedColor; // Textfield case kColorId_TextfieldDefaultColor: - return system_colors_[COLOR_WINDOWTEXT]; + return system_colors_[SystemThemeColor::kWindowText]; case kColorId_TextfieldDefaultBackground: - return system_colors_[COLOR_WINDOW]; + return system_colors_[SystemThemeColor::kWindow]; case kColorId_TextfieldReadOnlyColor: - return system_colors_[COLOR_GRAYTEXT]; + return system_colors_[SystemThemeColor::kGrayText]; case kColorId_TextfieldReadOnlyBackground: - return system_colors_[COLOR_3DFACE]; + return system_colors_[SystemThemeColor::kButtonFace]; case kColorId_TextfieldSelectionColor: - return system_colors_[COLOR_HIGHLIGHTTEXT]; + return system_colors_[SystemThemeColor::kHighlightText]; case kColorId_TextfieldSelectionBackgroundFocused: - return system_colors_[COLOR_HIGHLIGHT]; + return system_colors_[SystemThemeColor::kHighlight]; // Tooltip case kColorId_TooltipBackground: - return system_colors_[COLOR_WINDOW]; + return system_colors_[SystemThemeColor::kWindow]; case kColorId_TooltipText: - return system_colors_[COLOR_WINDOWTEXT]; + return system_colors_[SystemThemeColor::kWindowText]; // Tree // NOTE: these aren't right for all themes, but as close as I could get. case kColorId_TreeBackground: - return system_colors_[COLOR_WINDOW]; + return system_colors_[SystemThemeColor::kWindow]; case kColorId_TreeText: - return system_colors_[COLOR_WINDOWTEXT]; + return system_colors_[SystemThemeColor::kWindowText]; case kColorId_TreeSelectedText: - return system_colors_[COLOR_HIGHLIGHTTEXT]; + return system_colors_[SystemThemeColor::kHighlightText]; case kColorId_TreeSelectedTextUnfocused: - return system_colors_[COLOR_BTNTEXT]; + return system_colors_[SystemThemeColor::kButtonText]; case kColorId_TreeSelectionBackgroundFocused: - return system_colors_[COLOR_HIGHLIGHT]; + return system_colors_[SystemThemeColor::kHighlight]; case kColorId_TreeSelectionBackgroundUnfocused: - return system_colors_[UsesHighContrastColors() ? COLOR_MENUHIGHLIGHT - : COLOR_BTNFACE]; + return system_colors_[UsesHighContrastColors() + ? SystemThemeColor::kMenuHighlight + : SystemThemeColor::kButtonFace]; // Table case kColorId_TableBackground: - return system_colors_[COLOR_WINDOW]; + return system_colors_[SystemThemeColor::kWindow]; case kColorId_TableText: - return system_colors_[COLOR_WINDOWTEXT]; + return system_colors_[SystemThemeColor::kWindowText]; case kColorId_TableSelectedText: - return system_colors_[COLOR_HIGHLIGHTTEXT]; + return system_colors_[SystemThemeColor::kHighlightText]; case kColorId_TableSelectedTextUnfocused: - return system_colors_[COLOR_BTNTEXT]; + return system_colors_[SystemThemeColor::kButtonText]; case kColorId_TableSelectionBackgroundFocused: - return system_colors_[COLOR_HIGHLIGHT]; + return system_colors_[SystemThemeColor::kHighlight]; case kColorId_TableSelectionBackgroundUnfocused: - return system_colors_[UsesHighContrastColors() ? COLOR_MENUHIGHLIGHT - : COLOR_BTNFACE]; + return system_colors_[UsesHighContrastColors() + ? SystemThemeColor::kMenuHighlight + : SystemThemeColor::kButtonFace]; case kColorId_TableGroupingIndicatorColor: - return system_colors_[COLOR_GRAYTEXT]; + return system_colors_[SystemThemeColor::kGrayText]; default: break; @@ -585,8 +614,8 @@ // as a string. However, this string is language dependent. Instead, to // account for non-English systems, sniff out the system colors to // determine the high contrast color scheme. - SkColor fg_color = system_colors_[COLOR_WINDOWTEXT]; - SkColor bg_color = system_colors_[COLOR_WINDOW]; + SkColor fg_color = system_colors_[SystemThemeColor::kWindowText]; + SkColor bg_color = system_colors_[SystemThemeColor::kWindow]; if (bg_color == SK_ColorWHITE && fg_color == SK_ColorBLACK) { return NativeTheme::PreferredColorScheme::kLight; } @@ -1167,8 +1196,10 @@ } // Draw it manually. - if ((system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_3DFACE]) && - (system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_WINDOW])) { + if ((system_colors_[SystemThemeColor::kScrollbar] != + system_colors_[SystemThemeColor::kButtonFace]) && + (system_colors_[SystemThemeColor::kScrollbar] != + system_colors_[SystemThemeColor::kWindow])) { FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); } else { SkPaint paint;
diff --git a/ui/native_theme/native_theme_win.h b/ui/native_theme/native_theme_win.h index 574559c..50481e31 100644 --- a/ui/native_theme/native_theme_win.h +++ b/ui/native_theme/native_theme_win.h
@@ -10,9 +10,6 @@ // NativeThemeWin::instance(). // For more information on visual style parts and states, see: // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp - -#include <map> - #include <windows.h> #include "base/compiler_specific.h" @@ -94,8 +91,6 @@ NativeThemeWin(); ~NativeThemeWin() override; - mutable std::map<int, SkColor> system_colors_; - private: bool IsUsingHighContrastThemeInternal() const; void CloseHandlesInternal();
diff --git a/ui/native_theme/native_theme_win_unittest.cc b/ui/native_theme/native_theme_win_unittest.cc index a2864e55..9a30b71 100644 --- a/ui/native_theme/native_theme_win_unittest.cc +++ b/ui/native_theme/native_theme_win_unittest.cc
@@ -8,6 +8,7 @@ namespace ui { using Scheme = ui::NativeTheme::PreferredColorScheme; +using SystemThemeColor = ui::NativeTheme::SystemThemeColor; class TestNativeThemeWin : public NativeThemeWin { public: @@ -22,7 +23,7 @@ void SetUsesHighContrastColors(bool high_contrast) { high_contrast_ = high_contrast; } - void SetSystemColor(int system_color, SkColor color) { + void SetSystemColor(SystemThemeColor system_color, SkColor color) { system_colors_[system_color] = color; } @@ -44,15 +45,15 @@ ASSERT_EQ(theme.CalculatePreferredColorScheme(), Scheme::kLight); theme.SetUsesHighContrastColors(true); - theme.SetSystemColor(COLOR_WINDOW, SK_ColorBLACK); - theme.SetSystemColor(COLOR_WINDOWTEXT, SK_ColorWHITE); + theme.SetSystemColor(SystemThemeColor::kWindow, SK_ColorBLACK); + theme.SetSystemColor(SystemThemeColor::kWindowText, SK_ColorWHITE); ASSERT_EQ(theme.CalculatePreferredColorScheme(), Scheme::kDark); - theme.SetSystemColor(COLOR_WINDOW, SK_ColorWHITE); - theme.SetSystemColor(COLOR_WINDOWTEXT, SK_ColorBLACK); + theme.SetSystemColor(SystemThemeColor::kWindow, SK_ColorWHITE); + theme.SetSystemColor(SystemThemeColor::kWindowText, SK_ColorBLACK); ASSERT_EQ(theme.CalculatePreferredColorScheme(), Scheme::kLight); - theme.SetSystemColor(COLOR_WINDOWTEXT, SK_ColorBLUE); + theme.SetSystemColor(SystemThemeColor::kWindowText, SK_ColorBLUE); ASSERT_EQ(theme.CalculatePreferredColorScheme(), Scheme::kNoPreference); theme.SetUsesHighContrastColors(false);
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.cc b/ui/views/accessibility/view_ax_platform_node_delegate.cc index fed9566..0290635 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate.cc
@@ -487,8 +487,7 @@ ViewAXPlatformNodeDelegate* ax_delegate = static_cast<ViewAXPlatformNodeDelegate*>(&view_accessibility); if (ax_delegate) - is_ignored = is_ignored || (ax_delegate->GetData().role == - ax::mojom::Role::kIgnored); + is_ignored = is_ignored || ui::IsIgnored(ax_delegate->GetData()); return is_ignored; }), views_in_group->end());
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 4a4ee0c..a3f2499 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -461,9 +461,6 @@ } void Textfield::SetBackgroundColor(SkColor color) { - if (background_color_ == color) - return; - background_color_ = color; use_default_background_color_ = false; UpdateBackgroundColor(); @@ -482,9 +479,6 @@ } void Textfield::SetSelectionTextColor(SkColor color) { - if (selection_text_color_ == color) - return; - selection_text_color_ = color; use_default_selection_text_color_ = false; UpdateSelectionTextColor(); @@ -507,9 +501,6 @@ } void Textfield::SetSelectionBackgroundColor(SkColor color) { - if (selection_background_color_ == color) - return; - selection_background_color_ = color; use_default_selection_background_color_ = false; UpdateSelectionBackgroundColor();
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index dccc4e3d..14e97d2 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -22,6 +22,7 @@ #include "ui/views/widget/native_widget_private.h" #include "ui/views/widget/root_view.h" #include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_delegate.h" #include "ui/web_dialogs/web_dialog_delegate.h" #include "ui/web_dialogs/web_dialog_ui.h" @@ -39,11 +40,13 @@ WebDialogView::WebDialogView(content::BrowserContext* context, WebDialogDelegate* delegate, - std::unique_ptr<WebContentsHandler> handler) + std::unique_ptr<WebContentsHandler> handler, + bool use_dialog_frame) : ClientView(nullptr, nullptr), WebDialogWebContentsDelegate(context, std::move(handler)), delegate_(delegate), - web_view_(new views::WebView(context)) { + web_view_(new views::WebView(context)), + use_dialog_frame_(use_dialog_frame) { web_view_->set_allow_accelerators(true); AddChildView(web_view_); set_contents_view(web_view_); @@ -172,6 +175,12 @@ return this; } +NonClientFrameView* WebDialogView::CreateNonClientFrameView(Widget* widget) { + if (use_dialog_frame_) + return DialogDelegate::CreateDialogFrameView(widget); + return WidgetDelegate::CreateNonClientFrameView(widget); +} + views::View* WebDialogView::GetInitiallyFocusedView() { return web_view_; }
diff --git a/ui/views/controls/webview/web_dialog_view.h b/ui/views/controls/webview/web_dialog_view.h index f77676f..8f32667 100644 --- a/ui/views/controls/webview/web_dialog_view.h +++ b/ui/views/controls/webview/web_dialog_view.h
@@ -47,9 +47,12 @@ public views::WidgetDelegate { public: // |handler| must not be nullptr. + // |use_dialog_frame| indicates whether to use dialog frame view for non + // client frame view. WebDialogView(content::BrowserContext* context, ui::WebDialogDelegate* delegate, - std::unique_ptr<WebContentsHandler> handler); + std::unique_ptr<WebContentsHandler> handler, + bool use_dialog_frame = false); ~WebDialogView() override; // For testing. @@ -73,6 +76,7 @@ void WindowClosing() override; views::View* GetContentsView() override; ClientView* CreateClientView(views::Widget* widget) override; + NonClientFrameView* CreateNonClientFrameView(Widget* widget) override; views::View* GetInitiallyFocusedView() override; bool ShouldShowWindowTitle() const override; views::Widget* GetWidget() override; @@ -167,6 +171,9 @@ // Handler for unhandled key events from renderer. UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; + // Whether to use dialog frame view for non client frame view. + bool use_dialog_frame_ = false; + DISALLOW_COPY_AND_ASSIGN(WebDialogView); };
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index a173b43..df632c9 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -52,6 +52,19 @@ } // static +bool DialogDelegate::CanSupportCustomFrame(gfx::NativeView parent) { +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + // The new style doesn't support unparented dialogs on Linux desktop. + return parent != nullptr; +#elif defined(OS_WIN) + // The new style doesn't support unparented dialogs on Windows Classic themes. + if (!ui::win::IsAeroGlassEnabled()) + return parent != nullptr; +#endif + return true; +} + +// static Widget::InitParams DialogDelegate::GetDialogWidgetInitParams( WidgetDelegate* delegate, gfx::NativeWindow context, @@ -62,15 +75,8 @@ params.bounds = bounds; DialogDelegate* dialog = delegate->AsDialogDelegate(); -#if defined(OS_LINUX) && !defined(OS_CHROMEOS) - // The new style doesn't support unparented dialogs on Linux desktop. if (dialog) - dialog->supports_custom_frame_ &= parent != nullptr; -#elif defined(OS_WIN) - // The new style doesn't support unparented dialogs on Windows Classic themes. - if (dialog && !ui::win::IsAeroGlassEnabled()) - dialog->supports_custom_frame_ &= parent != nullptr; -#endif + dialog->supports_custom_frame_ &= CanSupportCustomFrame(parent); if (!dialog || dialog->ShouldUseCustomFrame()) { params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h index 0eb49e1a..1850f53 100644 --- a/ui/views/window/dialog_delegate.h +++ b/ui/views/window/dialog_delegate.h
@@ -42,6 +42,9 @@ gfx::NativeWindow context, gfx::NativeView parent); + // Whether using custom dialog frame is supported for this dialog. + static bool CanSupportCustomFrame(gfx::NativeView parent); + // Returns the dialog widget InitParams for a given |context| or |parent|. // If |bounds| is not empty, used to initially place the dialog, otherwise // a default location is used.