diff --git a/DEPS b/DEPS index 60b5743..c05e81f 100644 --- a/DEPS +++ b/DEPS
@@ -182,7 +182,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': '64c8b811b55aeb3c077dac0e32a12a3b40b1c128', + 'skia_revision': 'f80a78602e37d3236202465e0cdcad8800a79ff1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -194,7 +194,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': 'ebc6d0a4b9ecfb11275afa22f687378ab6a79e02', + 'angle_revision': 'f2d4abb2ef182108f3b87da301dbcb0fa949f8b1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -253,7 +253,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'b711c4303271b22b26ca982f6317c8297e39daee', + 'devtools_frontend_revision': '0a6d1c0a60fe51c52b0eea46ee658e6a198f814c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -875,7 +875,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cf77d6e387b6d0ce269f048e1f858e0ef27be2e5', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '84620d395a4d776f393a3c121544ff0b9b9c1c71', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1452,7 +1452,7 @@ }, 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'a4dfe24d7696145051c6929f778a100e6516d39c', + Var('webrtc_git') + '/src.git' + '@' + '1220c3995354a13294df51adcb4460d2338c6172', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1524,7 +1524,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@91a2d1d0265380b7d984c9d759f01390d11ba262', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@5e0e3b5576a5f5b0aec683f7a7e07b81e86881aa', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index 49c32bfd..07fa788d 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -2726,6 +2726,10 @@ <message name="IDS_TEST1"> Test string 1 </message> + <message name="IDS_TEST_STRING_NON_TRANSLATEABLE1" + translateable="false"> + Non translateable message 1, should be ignored + </message> </messages> </release> </grit> @@ -2741,6 +2745,10 @@ <message name="IDS_TEST2"> Test string 2 </message> + <message name="IDS_TEST_STRING_NON_TRANSLATEABLE2" + translateable="false"> + Non translateable message 2, should be ignored + </message> </messages> </release> </grit>
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index 990b82e..dd3208f 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -402,7 +402,6 @@ "java/src/org/chromium/android_webview/AwDebug.java", "java/src/org/chromium/android_webview/AwDevToolsServer.java", "java/src/org/chromium/android_webview/AwFeatureList.java", - "java/src/org/chromium/android_webview/AwFeatures.java", "java/src/org/chromium/android_webview/AwFormDatabase.java", "java/src/org/chromium/android_webview/AwGeolocationPermissions.java", "java/src/org/chromium/android_webview/AwHistogramRecorder.java", @@ -464,6 +463,7 @@ "java/src/org/chromium/android_webview/gfx/JavaBrowserViewRendererHelper.java", "java/src/org/chromium/android_webview/gfx/RootBeginFrameSourceWebView.java", "java/src/org/chromium/android_webview/metrics/AwMetricsServiceClient.java", + "java/src/org/chromium/android_webview/metrics/AwNonembeddedUmaReplayer.java", "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", @@ -475,7 +475,6 @@ ":common_aidl_java", ":common_crash_java", ":common_java", - ":common_metrics_java", ":common_platform_services_java", ":common_variations_java", ":resources", @@ -524,20 +523,6 @@ ] } -android_library("common_metrics_java") { - sources = [ - "java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java", - "java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaReplayer.java", - ] - deps = [ - ":common_aidl_java", - ":common_java", - "//android_webview/proto:metrics_bridge_records_proto_java", - "//base:base_java", - "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", - ] -} - android_library("common_variations_java") { sources = [ "java/src/org/chromium/android_webview/common/variations/VariationsServiceMetricsHelper.java", @@ -598,6 +583,7 @@ android_library("common_java") { sources = [ + "java/src/org/chromium/android_webview/common/AwFeatures.java", "java/src/org/chromium/android_webview/common/AwResource.java", "java/src/org/chromium/android_webview/common/AwSwitches.java", "java/src/org/chromium/android_webview/common/CommandLineUtil.java",
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java index e9ae1122..ca20f6f 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
@@ -24,7 +24,6 @@ import org.chromium.android_webview.AwContentsStatics; import org.chromium.android_webview.AwCookieManager; import org.chromium.android_webview.AwFeatureList; -import org.chromium.android_webview.AwFeatures; import org.chromium.android_webview.AwLocaleConfig; import org.chromium.android_webview.AwNetworkChangeNotifierRegistrationPolicy; import org.chromium.android_webview.AwProxyController; @@ -35,6 +34,7 @@ import org.chromium.android_webview.R; import org.chromium.android_webview.VariationsSeedLoader; import org.chromium.android_webview.WebViewChromiumRunQueue; +import org.chromium.android_webview.common.AwFeatures; import org.chromium.android_webview.common.AwResource; import org.chromium.android_webview.common.AwSwitches; import org.chromium.android_webview.gfx.AwDrawFnImpl;
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 e9c4b06..61d564c 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -19,11 +19,11 @@ import org.chromium.android_webview.common.AwSwitches; import org.chromium.android_webview.common.PlatformServiceBridge; -import org.chromium.android_webview.common.metrics.AwNonembeddedUmaReplayer; import org.chromium.android_webview.common.services.ICrashReceiverService; import org.chromium.android_webview.common.services.IMetricsBridgeService; import org.chromium.android_webview.common.services.ServiceNames; import org.chromium.android_webview.metrics.AwMetricsServiceClient; +import org.chromium.android_webview.metrics.AwNonembeddedUmaReplayer; import org.chromium.android_webview.policy.AwPolicyProvider; import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecord; import org.chromium.android_webview.safe_browsing.AwSafeBrowsingConfigHelper;
diff --git a/android_webview/java/src/org/chromium/android_webview/AwFeatures.java b/android_webview/java/src/org/chromium/android_webview/common/AwFeatures.java similarity index 92% rename from android_webview/java/src/org/chromium/android_webview/AwFeatures.java rename to android_webview/java/src/org/chromium/android_webview/common/AwFeatures.java index e582038..31033b0 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwFeatures.java +++ b/android_webview/java/src/org/chromium/android_webview/common/AwFeatures.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; /** * Constants for the names of WebView Features.
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 45e2ebb..f1c55c3 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -61,7 +61,7 @@ + "rendering engine)."), Flag.baseFeature("EnableSharedImageForWebview", "Enables shared images for WebView."), Flag.baseFeature("VizForWebView", "Enables Viz for WebView."), - Flag.baseFeature("WebViewConnectionlessSafeBrowsing", + Flag.baseFeature(AwFeatures.WEBVIEW_CONNECTIONLESS_SAFE_BROWSING, "Uses GooglePlayService's 'connectionless' APIs for Safe Browsing " + "security checks."), Flag.baseFeature(
diff --git a/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaReplayer.java b/android_webview/java/src/org/chromium/android_webview/metrics/AwNonembeddedUmaReplayer.java similarity index 98% rename from android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaReplayer.java rename to android_webview/java/src/org/chromium/android_webview/metrics/AwNonembeddedUmaReplayer.java index ef8be3b..6755a027 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaReplayer.java +++ b/android_webview/java/src/org/chromium/android_webview/metrics/AwNonembeddedUmaReplayer.java
@@ -1,7 +1,7 @@ // Copyright 2020 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.metrics; +package org.chromium.android_webview.metrics; import android.os.Bundle;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java index 28890d0b..de1a5b0 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/PopupWindowTest.java
@@ -4,6 +4,8 @@ package org.chromium.android_webview.test; +import android.graphics.Rect; +import android.net.Uri; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.webkit.JavascriptInterface; @@ -16,11 +18,14 @@ import org.junit.runner.RunWith; import org.chromium.android_webview.AwContents; +import org.chromium.android_webview.JsReplyProxy; +import org.chromium.android_webview.WebMessageListener; import org.chromium.android_webview.test.AwActivityTestRule.PopupInfo; import org.chromium.android_webview.test.TestAwContentsClient.ShouldInterceptRequestHelper; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.Feature; +import org.chromium.content_public.browser.MessagePort; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; @@ -31,6 +36,7 @@ import java.util.List; import java.util.Locale; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; /** @@ -364,6 +370,158 @@ Assert.assertFalse(onCreateWindowHelper.getIsUserGesture()); } + private static class TestWebMessageListener implements WebMessageListener { + private LinkedBlockingQueue<Data> mQueue = new LinkedBlockingQueue<>(); + + public static class Data { + public String mMessage; + public boolean mIsMainFrame; + public JsReplyProxy mReplyProxy; + + public Data(String message, boolean isMainFrame, JsReplyProxy replyProxy) { + mMessage = message; + mIsMainFrame = isMainFrame; + mReplyProxy = replyProxy; + } + } + + @Override + public void onPostMessage(String message, Uri sourceOrigin, boolean isMainFrame, + JsReplyProxy replyProxy, MessagePort[] ports) { + mQueue.add(new Data(message, isMainFrame, replyProxy)); + } + + public Data waitForOnPostMessage() throws Exception { + return AwActivityTestRule.waitForNextQueueElement(mQueue); + } + } + + // Regression test for crbug.com/1083819. + // + // The setup of this test is to have an iframe inside of a main frame, give the iframe user + // gesture, then window.open() on javascript: scheme. We are verifying that the + // JavaScript code isn't running in the main frame's context when + // getJavaScriptCanOpenWindowsAutomatically() is false. + // + // There are several steps in this test: + // 1. Load the web page (main.html), which has an cross-origin iframe (iframe.html). + // 2. main frame send a message to browser to establish the connection. + // 3. iframe send a message to browser to estiablish the connection and notify the location of + // the |iframe_link| element. + // 4. Click the iframe_link element to give user gesture. + // 5. Browser waits until receives "clicked" message. + // 6. Browser asks the iframe to call window.open() and waits for the "done" message. + // 7. Browser asks the main frame to check if an element was injected and waits the result. + @Test + @SmallTest + @Feature({"AndroidWebView"}) + public void testSingleWindowModeJsInjection() throws Throwable { + // Choose a free port which is different from |mWebServer| so they have different origins. + TestWebServer crossOriginWebServer = TestWebServer.startAdditional(); + + final String windowOpenJavaScript = "javascript:{" + + " let elem = document.createElement('p');" + + " elem.setAttribute('id', 'inject');" + + " document.body.append(elem);" + + "}"; + final String iframeHtml = "<html><head>" + + "<script>" + + " myObject.onmessage = function(e) {" + + " window.open(\"" + windowOpenJavaScript + "\");" + + " myObject.postMessage('done');" + + " };" + + " window.onload = function() {" + + " let link = document.getElementById('iframe_link');" + + " let rect = link.getBoundingClientRect();" + + " let message = Math.round(rect.left) + ';' + Math.round(rect.top) + ';';" + + " message += Math.round(rect.right) + ';' + Math.round(rect.bottom);" + + " myObject.postMessage(message);" + + " };" + + "</script>" + + "</head><body>" + + " <div>I am iframe.</div>" + + " <a href='#' id='iframe_link' onclick='myObject.postMessage(\"clicked\");'>" + + " iframe link" + + " </a>" + + "</body></html>"; + final String iframeHtmlPath = + crossOriginWebServer.setResponse("/iframe.html", iframeHtml, null); + final String mainHtml = "<html><head><script>" + + " myObject.onmessage = function(e) {" + + " let elem = document.getElementById('inject');" + + " if (elem) { myObject.postMessage('failed'); }" + + " else { myObject.postMessage('succeed'); }" + + " };" + + " myObject.postMessage('init');" + + "</script></head><body>" + + "<iframe src='" + iframeHtmlPath + "'></iframe>" + + "<div>I am main frame</div>" + + "</body></html>"; + final String mainHtmlPath = mWebServer.setResponse("/main.html", mainHtml, null); + + TestWebMessageListener webMessageListener = new TestWebMessageListener(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mParentContents.getSettings().setJavaScriptEnabled(true); + // |false| is the default setting for setSupportMultipleWindows(), we explicitly set it + // to |false| here for better readability. + mParentContents.getSettings().setSupportMultipleWindows(false); + mParentContents.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); + mParentContents.addWebMessageListener( + "myObject", new String[] {"*"}, webMessageListener); + }); + + // Step 1. + mActivityTestRule.loadUrlSync( + mParentContents, mParentContentsClient.getOnPageFinishedHelper(), mainHtmlPath); + + // Step 2 and 3, the sequence doesn't matter. + JsReplyProxy mainFrameReplyProxy = null; + JsReplyProxy iframeReplyProxy = null; + Rect rect = null; + for (int i = 0; i < 2; ++i) { + TestWebMessageListener.Data data = webMessageListener.waitForOnPostMessage(); + if (data.mIsMainFrame) { + // The connection between browser and main frame established. + Assert.assertEquals("init", data.mMessage); + mainFrameReplyProxy = data.mReplyProxy; + } else { + // The connection between browser and iframe established. + iframeReplyProxy = data.mReplyProxy; + // iframe_link location. + String[] c = data.mMessage.split(";"); + rect = new Rect(Integer.parseInt(c[0]), Integer.parseInt(c[1]), + Integer.parseInt(c[2]), Integer.parseInt(c[3])); + } + } + + Assert.assertNotNull("rect should not be null", rect); + Assert.assertNotNull("mainFrameReplyProxy should not be null.", mainFrameReplyProxy); + Assert.assertNotNull("iframeReplyProxy should not be null.", iframeReplyProxy); + + // Step 4. Click iframe_link to give user gesture. + DOMUtils.clickRect(mParentContents.getWebContents(), rect); + + // Step 5. Waits until the element got clicked. + TestWebMessageListener.Data clicked = webMessageListener.waitForOnPostMessage(); + Assert.assertEquals("clicked", clicked.mMessage); + + // Step 6. Send an arbitrary message to call window.open on javascript: URI. + iframeReplyProxy.postMessage("hello"); + TestWebMessageListener.Data data = webMessageListener.waitForOnPostMessage(); + Assert.assertEquals("done", data.mMessage); + + // Step 7. Send an arbitrary message to trigger the check. Main frame will check if there is + // an injected element by running |windowOpenJavaScript|. + mainFrameReplyProxy.postMessage("hello"); + + // If |succeed| received, then there was no injection. + TestWebMessageListener.Data data2 = webMessageListener.waitForOnPostMessage(); + Assert.assertEquals("succeed", data2.mMessage); + + // Cleanup the test web server. + crossOriginWebServer.shutdown(); + } + // Copied from imeTest.java. private void assertWaitForSelectActionBarStatus( boolean show, final SelectionPopupController controller) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/common/metrics/AwNonembeddedUmaRecorderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/devui/AwNonembeddedUmaRecorderTest.java similarity index 98% rename from android_webview/javatests/src/org/chromium/android_webview/test/common/metrics/AwNonembeddedUmaRecorderTest.java rename to android_webview/javatests/src/org/chromium/android_webview/test/devui/AwNonembeddedUmaRecorderTest.java index 2df5bb6a..07f1d73 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/common/metrics/AwNonembeddedUmaRecorderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/devui/AwNonembeddedUmaRecorderTest.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.common.metrics; +package org.chromium.android_webview.test.devui; import static org.chromium.android_webview.test.OnlyRunIn.ProcessMode.SINGLE_PROCESS; @@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.android_webview.common.metrics.AwNonembeddedUmaRecorder; +import org.chromium.android_webview.nonembedded.AwNonembeddedUmaRecorder; import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecord; import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecord.RecordType; import org.chromium.android_webview.test.AwJUnit4ClassRunner;
diff --git a/android_webview/junit/src/org/chromium/android_webview/robolectric/common/metrics/AwNonembeddedUmaReplayerTest.java b/android_webview/junit/src/org/chromium/android_webview/robolectric/metrics/AwNonembeddedUmaReplayerTest.java similarity index 96% rename from android_webview/junit/src/org/chromium/android_webview/robolectric/common/metrics/AwNonembeddedUmaReplayerTest.java rename to android_webview/junit/src/org/chromium/android_webview/robolectric/metrics/AwNonembeddedUmaReplayerTest.java index f47d8d8b..b81aaca 100644 --- a/android_webview/junit/src/org/chromium/android_webview/robolectric/common/metrics/AwNonembeddedUmaReplayerTest.java +++ b/android_webview/junit/src/org/chromium/android_webview/robolectric/metrics/AwNonembeddedUmaReplayerTest.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.robolectric.common.metrics; +package org.chromium.android_webview.robolectric.metrics; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -15,7 +15,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.chromium.android_webview.common.metrics.AwNonembeddedUmaReplayer; +import org.chromium.android_webview.metrics.AwNonembeddedUmaReplayer; import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecord; import org.chromium.android_webview.proto.MetricsBridgeRecords.HistogramRecord.RecordType; import org.chromium.base.metrics.UmaRecorder;
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index 2c8e287b..782bad9 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -14,6 +14,7 @@ # as a library. android_library("nonembedded_java") { sources = [ + "java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java", "java/src/org/chromium/android_webview/nonembedded/LicenseActivity.java", "java/src/org/chromium/android_webview/nonembedded/LicenseContentProvider.java", "java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java", @@ -22,12 +23,14 @@ ":devui_java", ":services_java", "//android_webview:android_webview_product_config_java", + "//android_webview:common_aidl_java", "//android_webview:common_java", - "//android_webview:common_metrics_java", + "//android_webview/proto:metrics_bridge_records_proto_java", "//base:base_java", "//base:jni_java", "//components/about_ui/android:aboutui_java", "//components/embedder_support/android:application_java", + "//third_party/android_deps:com_google_protobuf_protobuf_javalite_java", "//ui/android:ui_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -56,7 +59,6 @@ "//android_webview:common_aidl_java", "//android_webview:common_crash_java", "//android_webview:common_java", - "//android_webview:common_metrics_java", "//android_webview:common_platform_services_java", "//base:base_java", "//components/minidump_uploader:minidump_uploader_java", @@ -84,7 +86,6 @@ "//android_webview:common_aidl_java", "//android_webview:common_crash_java", "//android_webview:common_java", - "//android_webview:common_metrics_java", "//android_webview:common_platform_services_java", "//android_webview:common_variations_java", "//android_webview/proto:metrics_bridge_records_proto_java",
diff --git a/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java similarity index 98% rename from android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java rename to android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java index 960ad50..2124577 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/metrics/AwNonembeddedUmaRecorder.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwNonembeddedUmaRecorder.java
@@ -1,7 +1,7 @@ // Copyright 2020 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.metrics; +package org.chromium.android_webview.nonembedded; import android.content.ComponentName; import android.content.Context;
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java index b3a057cf..b580a323 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/WebViewApkApplication.java
@@ -11,7 +11,6 @@ import org.chromium.android_webview.AwLocaleConfig; import org.chromium.android_webview.common.CommandLineUtil; -import org.chromium.android_webview.common.metrics.AwNonembeddedUmaRecorder; import org.chromium.android_webview.devui.util.WebViewPackageHelper; import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils;
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index 4b81910f..df50699 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -161,7 +161,6 @@ "//android_webview:android_webview_java", "//android_webview:common_aidl_java", "//android_webview:common_crash_java", - "//android_webview:common_metrics_java", "//android_webview:common_platform_services_java", "//android_webview:common_variations_java", "//android_webview/nonembedded:devui_java", @@ -302,8 +301,8 @@ "../javatests/src/org/chromium/android_webview/test/WebViewModalDialogOverrideTest.java", "../javatests/src/org/chromium/android_webview/test/common/crash/CrashInfoEqualityMatcher.java", "../javatests/src/org/chromium/android_webview/test/common/crash/CrashInfoTest.java", - "../javatests/src/org/chromium/android_webview/test/common/metrics/AwNonembeddedUmaRecorderTest.java", "../javatests/src/org/chromium/android_webview/test/common/variations/VariationsUtilsTest.java", + "../javatests/src/org/chromium/android_webview/test/devui/AwNonembeddedUmaRecorderTest.java", "../javatests/src/org/chromium/android_webview/test/devui/DeveloperUiTest.java", "../javatests/src/org/chromium/android_webview/test/devui/util/CrashBugUrlFactoryTest.java", "../javatests/src/org/chromium/android_webview/test/devui/util/UnuploadedFilesStateLoaderTest.java", @@ -475,13 +474,12 @@ "../junit/src/org/chromium/android_webview/robolectric/AwScrollOffsetManagerTest.java", "../junit/src/org/chromium/android_webview/robolectric/FindAddressTest.java", "../junit/src/org/chromium/android_webview/robolectric/common/FlagOverrideHelperTest.java", - "../junit/src/org/chromium/android_webview/robolectric/common/metrics/AwNonembeddedUmaReplayerTest.java", "../junit/src/org/chromium/android_webview/robolectric/common/services/ServiceNamesTest.java", + "../junit/src/org/chromium/android_webview/robolectric/metrics/AwNonembeddedUmaReplayerTest.java", ] deps = [ "//android_webview:android_webview_java", - "//android_webview:common_metrics_java", "//android_webview/nonembedded:services_java", "//android_webview/proto:metrics_bridge_records_proto_java", "//base:base_java",
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc index 5154cc0..0ac06329 100644 --- a/ash/accessibility/accessibility_controller_impl.cc +++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -597,8 +597,10 @@ user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); // TODO(crbug.com/1085442): Work with UX to pick default color, and consider // storing this as an index into a color array or as a hex color string. + // For now this should match a color in cursorColorOptions_ from + // manage_a11y_page.js. registry->RegisterIntegerPref( - prefs::kAccessibilityCursorColor, SK_ColorBLUE, + prefs::kAccessibilityCursorColor, 0xaa00ff, user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); registry->RegisterBooleanPref( prefs::kAccessibilityDictationEnabled, false,
diff --git a/ash/app_list/views/assistant/assistant_privacy_info_view.cc b/ash/app_list/views/assistant/assistant_privacy_info_view.cc index 0080e01..084d6ff 100644 --- a/ash/app_list/views/assistant/assistant_privacy_info_view.cc +++ b/ash/app_list/views/assistant/assistant_privacy_info_view.cc
@@ -15,7 +15,8 @@ AssistantPrivacyInfoView::AssistantPrivacyInfoView( AppListViewDelegate* view_delegate, SearchResultPageView* search_result_page_view) - : PrivacyInfoView(IDS_APP_LIST_ASSISTANT_PRIVACY_INFO), + : PrivacyInfoView(IDS_APP_LIST_ASSISTANT_PRIVACY_INFO, + IDS_APP_LIST_LEARN_MORE), view_delegate_(view_delegate), search_result_page_view_(search_result_page_view) {} @@ -27,7 +28,7 @@ return; view_delegate_->MarkAssistantPrivacyInfoDismissed(); - search_result_page_view_->OnAssistantPrivacyInfoViewCloseButtonPressed(); + search_result_page_view_->OnPrivacyInfoViewCloseButtonPressed(); } void AssistantPrivacyInfoView::StyledLabelLinkClicked(views::StyledLabel* label,
diff --git a/ash/app_list/views/privacy_info_view.cc b/ash/app_list/views/privacy_info_view.cc index cb664aa..4bd5a15 100644 --- a/ash/app_list/views/privacy_info_view.cc +++ b/ash/app_list/views/privacy_info_view.cc
@@ -32,8 +32,10 @@ } // namespace -PrivacyInfoView::PrivacyInfoView(const int info_string_id) { - InitLayout(info_string_id); +PrivacyInfoView::PrivacyInfoView(const int info_string_id, + const int link_string_id) + : info_string_id_(info_string_id), link_string_id_(link_string_id) { + InitLayout(); } PrivacyInfoView::~PrivacyInfoView() = default; @@ -84,7 +86,7 @@ } } -void PrivacyInfoView::InitLayout(const int info_string_id) { +void PrivacyInfoView::InitLayout() { SetLayoutManager(std::make_unique<views::FillLayout>()); SetBorder(views::CreateEmptyBorder(gfx::Insets(kRowMarginDip))); row_container_ = AddChildView(std::make_unique<views::View>()); @@ -108,7 +110,7 @@ InitInfoIcon(); // Text. - InitText(info_string_id); + InitText(); // Spacer. layout_manager->SetFlexForView( @@ -126,12 +128,11 @@ gfx::kGoogleBlue600)); } -void PrivacyInfoView::InitText(const int info_string_id) { - const base::string16 link = - l10n_util::GetStringUTF16(IDS_APP_LIST_LEARN_MORE); +void PrivacyInfoView::InitText() { + const base::string16 link = l10n_util::GetStringUTF16(link_string_id_); size_t offset; const base::string16 text = - l10n_util::GetStringFUTF16(info_string_id, link, &offset); + l10n_util::GetStringFUTF16(info_string_id_, link, &offset); auto text_view = std::make_unique<views::StyledLabel>(text, this); views::StyledLabel::RangeStyleInfo style; style.custom_font = text_view->GetDefaultFontList().Derive( @@ -155,9 +156,7 @@ gfx::kGoogleGrey700)); close_button->SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); close_button->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE); - // TODO(crbug/1079169): Create a new string that is not Assistant-specific. - base::string16 close_button_label( - l10n_util::GetStringUTF16(IDS_APP_LIST_ASSISTANT_PRIVACY_INFO_CLOSE)); + base::string16 close_button_label(l10n_util::GetStringUTF16(IDS_APP_CLOSE)); close_button->SetAccessibleName(close_button_label); close_button->SetTooltipText(close_button_label); close_button->SetFocusBehavior(FocusBehavior::ALWAYS);
diff --git a/ash/app_list/views/privacy_info_view.h b/ash/app_list/views/privacy_info_view.h index aa56fe13..7d5f765 100644 --- a/ash/app_list/views/privacy_info_view.h +++ b/ash/app_list/views/privacy_info_view.h
@@ -34,14 +34,14 @@ void OnGestureEvent(ui::GestureEvent* event) override; protected: - explicit PrivacyInfoView(int info_string_id); + PrivacyInfoView(int info_string_id, int link_string_id); bool IsCloseButton(views::Button* button) const; private: - void InitLayout(int info_string_id); + void InitLayout(); void InitInfoIcon(); - void InitText(int info_string_id); + void InitText(); void InitCloseButton(); views::View* row_container_ = nullptr; // Owned by view hierarchy. @@ -49,6 +49,9 @@ views::StyledLabel* text_view_ = nullptr; // Owned by view hierarchy. views::ImageButton* close_button_ = nullptr; // Owned by view hierarchy. + const int info_string_id_; + const int link_string_id_; + DISALLOW_COPY_AND_ASSIGN(PrivacyInfoView); };
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc index 35b0ef7..4b78825 100644 --- a/ash/app_list/views/search_result_page_view.cc +++ b/ash/app_list/views/search_result_page_view.cc
@@ -440,7 +440,7 @@ void SearchResultPageView::ShowAssistantChanged() {} -void SearchResultPageView::OnAssistantPrivacyInfoViewCloseButtonPressed() { +void SearchResultPageView::OnPrivacyInfoViewCloseButtonPressed() { ReorderSearchResultContainers(); }
diff --git a/ash/app_list/views/search_result_page_view.h b/ash/app_list/views/search_result_page_view.h index 7c542c4..1644521 100644 --- a/ash/app_list/views/search_result_page_view.h +++ b/ash/app_list/views/search_result_page_view.h
@@ -93,7 +93,7 @@ void SearchEngineChanged() override; void ShowAssistantChanged() override; - void OnAssistantPrivacyInfoViewCloseButtonPressed(); + void OnPrivacyInfoViewCloseButtonPressed(); // Shows a dialog widget, and anchors it within the search results page. The // dialog will be positioned relative to the search box bounds, and will be
diff --git a/ash/shell_delegate.cc b/ash/shell_delegate.cc index 6fe43b7..14d6a02 100644 --- a/ash/shell_delegate.cc +++ b/ash/shell_delegate.cc
@@ -6,6 +6,14 @@ namespace ash { +bool ShellDelegate::AllowDefaultTouchActions(gfx::NativeWindow window) { + return true; +} + +bool ShellDelegate::ShouldWaitForTouchPressAck(gfx::NativeWindow window) { + return false; +} + bool ShellDelegate::IsTabDrag(const ui::OSExchangeData& drop_data) { return false; }
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h index b84c2e01..997fbb6f 100644 --- a/ash/shell_delegate.h +++ b/ash/shell_delegate.h
@@ -58,6 +58,16 @@ // Check whether the current tab of the browser window can go back. virtual bool CanGoBack(gfx::NativeWindow window) const = 0; + // Returns true if |window| allows default touch behaviors. If false, it means + // no default touch behavior is allowed (i.e., the touch action of window is + // cc::TouchAction::kNone). This function is used by BackGestureEventHandler + // to decide if we can perform the system default back gesture. + virtual bool AllowDefaultTouchActions(gfx::NativeWindow window); + + // Returns true if we should wait for touch press ack when deciding if back + // gesture can be performed. + virtual bool ShouldWaitForTouchPressAck(gfx::NativeWindow window); + // Checks whether a drag-drop operation is a tab drag. virtual bool IsTabDrag(const ui::OSExchangeData& drop_data);
diff --git a/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc b/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc index 2847d58..f0939f6 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_event_handler.cc
@@ -13,6 +13,7 @@ #include "ash/session/session_controller_impl.h" #include "ash/shelf/contextual_tooltip.h" #include "ash/shell.h" +#include "ash/shell_delegate.h" #include "ash/wm/gestures/back_gesture/back_gesture_affordance.h" #include "ash/wm/gestures/back_gesture/back_gesture_contextual_nudge_controller_impl.h" #include "ash/wm/overview/overview_controller.h" @@ -26,6 +27,7 @@ #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/wm/core/coordinate_conversion.h" +#include "ui/wm/core/window_util.h" namespace ash { @@ -170,7 +172,20 @@ } } -void BackGestureEventHandler::OnGestureEvent(ui::GestureEvent* event) {} +void BackGestureEventHandler::OnGestureEvent(ui::GestureEvent* event) { + if (should_wait_for_touch_ack_) { + aura::Window* target = static_cast<aura::Window*>(event->target()); + gfx::Point screen_location = event->location(); + ::wm::ConvertPointToScreen(target, &screen_location); + if (MaybeHandleBackGesture(event, screen_location)) + event->StopPropagation(); + + // Reset |should_wait_for_touch_ack_| for the last gesture event in the + // sequence. + if (event->type() == ui::ET_GESTURE_END) + should_wait_for_touch_ack_ = false; + } +} void BackGestureEventHandler::OnTouchEvent(ui::TouchEvent* event) { // Do not handle PEN and ERASER events for back gesture. PEN events can come @@ -208,14 +223,6 @@ } last_touch_point_ = event->location(); - ui::TouchEvent touch_event_copy = *event; - if (!gesture_provider_.OnTouchEvent(&touch_event_copy)) - return; - - gesture_provider_.OnTouchEventAck( - touch_event_copy.unique_event_id(), /*event_consumed=*/false, - /*is_source_touch_event_set_non_blocking=*/false); - // Get the event target from TouchEvent since target of the GestureEvent // from GetAndResetPendingGestures is nullptr. The coordinate conversion is // done outside the loop as the previous gesture events in a sequence may @@ -226,11 +233,28 @@ aura::Window* target = static_cast<aura::Window*>(event->target()); gfx::Point screen_location = event->location(); ::wm::ConvertPointToScreen(target, &screen_location); - const std::vector<std::unique_ptr<ui::GestureEvent>> gestures = - gesture_provider_.GetAndResetPendingGestures(); - for (const auto& gesture : gestures) { - if (MaybeHandleBackGesture(gesture.get(), screen_location)) - event->StopPropagation(); + + if (event->type() == ui::ET_TOUCH_PRESSED && + ShouldWaitForTouchPressAck(screen_location)) { + should_wait_for_touch_ack_ = true; + return; + } + + if (!should_wait_for_touch_ack_) { + ui::TouchEvent touch_event_copy = *event; + if (!gesture_provider_.OnTouchEvent(&touch_event_copy)) + return; + + gesture_provider_.OnTouchEventAck( + touch_event_copy.unique_event_id(), /*event_consumed=*/false, + /*is_source_touch_event_set_non_blocking=*/false); + + std::vector<std::unique_ptr<ui::GestureEvent>> gestures = + gesture_provider_.GetAndResetPendingGestures(); + for (const auto& gesture : gestures) { + if (MaybeHandleBackGesture(gesture.get(), screen_location)) + event->StopPropagation(); + } } } @@ -386,6 +410,8 @@ if (!top_window && !shell->overview_controller()->InOverviewSession()) return false; + // If the event location falls into the window's gesture exclusion zone, do + // not handle it. for (aura::Window* window = top_window; window; window = window->parent()) { SkRegion* gesture_exclusion = window->GetProperty(kSystemGestureExclusionKey); @@ -399,6 +425,10 @@ } } + // If the target window does not allow touch action, do not handle it. + if (!Shell::Get()->shell_delegate()->AllowDefaultTouchActions(top_window)) + return false; + gfx::Rect hit_bounds_in_screen(display::Screen::GetScreen() ->GetDisplayNearestWindow(top_window) .work_area()); @@ -421,4 +451,14 @@ BackGestureEndType::kBack)); } +bool BackGestureEventHandler::ShouldWaitForTouchPressAck( + const gfx::Point& screen_location) { + if (!CanStartGoingBack(screen_location)) + return false; + + aura::Window* top_window = window_util::GetTopWindow(); + return !top_window->GetProperty(kIsShowingInOverviewKey) && + Shell::Get()->shell_delegate()->ShouldWaitForTouchPressAck(top_window); +} + } // namespace ash
diff --git a/ash/wm/gestures/back_gesture/back_gesture_event_handler.h b/ash/wm/gestures/back_gesture/back_gesture_event_handler.h index b8551b2..50a072a 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_event_handler.h +++ b/ash/wm/gestures/back_gesture/back_gesture_event_handler.h
@@ -58,6 +58,12 @@ void SendBackEvent(const gfx::Point& screen_location); + // Returns true if we should wait for touch press ack to decide whether to + // show back gesture. If true, BackGestureEventHandler should not handle touch + // press event in OnTouchEvent() but should wait after touch ack has been + // received. + bool ShouldWaitForTouchPressAck(const gfx::Point& screen_location); + // True if swiping from left edge to go to previous page is in progress. bool going_back_started_ = false; @@ -98,6 +104,13 @@ // instead of going back. ui::GestureProviderAura gesture_provider_; + // False if BackGestureEventHandler should not handle touch events directly in + // OnTouchEvent(), but should wait after touch ack is received. This is needed + // as the window's touch action (if exist) will only be set after it sees the + // touch start event and we'll need the touch action information to decide + // whether back gesture should be shown. + bool should_wait_for_touch_ack_ = false; + // Start scenario type of the back gesture, used for related metrics. BackGestureStartScenarioType back_gesture_start_scenario_type_ = BackGestureStartScenarioType::kMaxValue;
diff --git a/base/BUILD.gn b/base/BUILD.gn index d06811b..e67a0ed0 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1524,6 +1524,8 @@ "fuchsia/fuchsia_logging.h", "fuchsia/intl_profile_watcher.cc", "fuchsia/intl_profile_watcher.h", + "fuchsia/process_context.cc", + "fuchsia/process_context.h", "fuchsia/scoped_service_binding.cc", "fuchsia/scoped_service_binding.h", "fuchsia/service_provider_impl.cc", @@ -1592,6 +1594,7 @@ "//third_party/fuchsia-sdk/sdk/pkg/async-loop-cpp", "//third_party/fuchsia-sdk/sdk/pkg/async-loop-default", "//third_party/fuchsia-sdk/sdk/pkg/fidl", + "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp", "//third_party/fuchsia-sdk/sdk/pkg/syslog", "//third_party/fuchsia-sdk/sdk/pkg/vfs_cpp", "//third_party/icu",
diff --git a/base/fuchsia/default_context.h b/base/fuchsia/default_context.h index 4484f10f9..3fc88389 100644 --- a/base/fuchsia/default_context.h +++ b/base/fuchsia/default_context.h
@@ -16,8 +16,11 @@ namespace base { namespace fuchsia { + +// TODO(https://crbug.com/1090364): Move this to process_context.h. // Returns default sys::ComponentContext for the current process. BASE_EXPORT sys::ComponentContext* ComponentContextForCurrentProcess(); + } // namespace fuchsia // Replaces the default sys::ComponentContext for the current process, and
diff --git a/base/fuchsia/process_context.cc b/base/fuchsia/process_context.cc new file mode 100644 index 0000000..eed0666 --- /dev/null +++ b/base/fuchsia/process_context.cc
@@ -0,0 +1,20 @@ +// Copyright 2020 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/fuchsia/process_context.h" + +#include <lib/sys/inspect/cpp/component.h> + +#include "base/fuchsia/default_context.h" +#include "base/no_destructor.h" + +namespace base { + +sys::ComponentInspector* ComponentInspectorForProcess() { + static base::NoDestructor<sys::ComponentInspector> value( + fuchsia::ComponentContextForCurrentProcess()); + return value.get(); +} + +} // namespace base
diff --git a/base/fuchsia/process_context.h b/base/fuchsia/process_context.h new file mode 100644 index 0000000..bbeee31 --- /dev/null +++ b/base/fuchsia/process_context.h
@@ -0,0 +1,21 @@ +// Copyright 2020 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_FUCHSIA_PROCESS_CONTEXT_H_ +#define BASE_FUCHSIA_PROCESS_CONTEXT_H_ + +#include "base/base_export.h" + +namespace sys { +class ComponentInspector; +} // namespace sys + +namespace base { + +// Returns sys::ComponentInspector for the current process. +BASE_EXPORT sys::ComponentInspector* ComponentInspectorForProcess(); + +} // namespace base + +#endif // BASE_FUCHSIA_PROCESS_CONTEXT_H_
diff --git a/base/profiler/metadata_recorder.cc b/base/profiler/metadata_recorder.cc index a6e3cc2..f140c25 100644 --- a/base/profiler/metadata_recorder.cc +++ b/base/profiler/metadata_recorder.cc
@@ -113,15 +113,10 @@ size_t MetadataRecorder::MetadataProvider::GetItems( ItemArray* const items) const { - // Assertion is only necessary so that thread annotations recognize that - // |read_lock_| is acquired. - metadata_recorder_->read_lock_.AssertAcquired(); return metadata_recorder_->GetItems(items); } size_t MetadataRecorder::GetItems(ItemArray* const items) const { - read_lock_.AssertAcquired(); - // If a writer adds a new item after this load, it will be ignored. We do // this instead of calling item_slots_used_.load() explicitly in the for loop // bounds checking, which would be expensive.
diff --git a/base/profiler/metadata_recorder.h b/base/profiler/metadata_recorder.h index 6e120dd4..86296348 100644 --- a/base/profiler/metadata_recorder.h +++ b/base/profiler/metadata_recorder.h
@@ -187,8 +187,10 @@ // Retrieves the first |available_slots| items in the metadata recorder and // copies them into |items|, returning the number of metadata items that // were copied. To ensure that all items can be copied, |available slots| - // should be greater than or equal to |MAX_METADATA_COUNT|. - size_t GetItems(ItemArray* const items) const; + // should be greater than or equal to |MAX_METADATA_COUNT|. Requires + // NO_THREAD_SAFETY_ANALYSIS because clang's analyzer doesn't understand the + // cross-class locking used in this class' implementation. + size_t GetItems(ItemArray* const items) const NO_THREAD_SAFETY_ANALYSIS; private: const MetadataRecorder* const metadata_recorder_;
diff --git a/chrome/android/java/res/layout/autofill_local_card_editor.xml b/chrome/android/java/res/layout/autofill_local_card_editor.xml index e8a4c14..66564af 100644 --- a/chrome/android/java/res/layout/autofill_local_card_editor.xml +++ b/chrome/android/java/res/layout/autofill_local_card_editor.xml
@@ -113,7 +113,6 @@ <com.google.android.material.textfield.TextInputLayout android:id="@+id/credit_card_nickname_label" android:labelFor="@+id/credit_card_nickname_edit" - app:counterEnabled="true" app:counterMaxLength="25" app:errorEnabled="true" android:layout_width="match_parent"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalCardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalCardEditor.java index 9aff4950..43da55e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalCardEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillLocalCardEditor.java
@@ -78,6 +78,8 @@ // Set the visibility of the nickname field based on the experiment flag. mNicknameLabel.setVisibility(isNicknameManagementEnabled() ? View.VISIBLE : View.GONE); mNicknameText.addTextChangedListener(nicknameTextWatcher()); + mNicknameText.setOnFocusChangeListener( + (view, hasFocus) -> mNicknameLabel.setCounterEnabled(hasFocus)); // Set text watcher to format credit card number mNumberText.addTextChangedListener(new CreditCardNumberFormattingTextWatcher());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java index b71cdd9..48082a0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java
@@ -18,6 +18,8 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.tab.SadTab; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; +import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.ui.UiUtils; import org.chromium.ui.base.WindowAndroid; @@ -131,6 +133,14 @@ // and Android views should be captured in the screenshot. if (chromeActivity.getBottomSheetController().isSheetOpen()) return false; + // If the start surface or the grid tab switcher are in use, do not use the compositor, it + // will snapshot the last active tab instead of the current screen if we try to use it. + if (chromeActivity.isInOverviewMode() + && (StartSurfaceConfiguration.isStartSurfaceEnabled() + || TabUiFeatureUtilities.isGridTabSwitcherEnabled())) { + return false; + } + // If the tab is null, assume in the tab switcher so a Compositor snapshot is good. if (currentTab == null) return true; // If the tab is not interactable, also assume in the tab switcher.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index bc570cc..1774318d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -131,10 +131,6 @@ private final PropertyModel mListPropertyModel; private final List<Runnable> mDeferredNativeRunnables = new ArrayList<Runnable>(); private final Handler mHandler; - // TODO(crbug.com/982818): make EditUrlProcessor behave like all other processors and register - // it in the mSuggestionProcessors list. The processor currently cannot be combined with - // other processors because of its unique requirements. - private @Nullable EditUrlSuggestionProcessor mEditUrlProcessor; private HeaderProcessor mHeaderProcessor; private final List<SuggestionProcessor> mSuggestionProcessors; private final List<DropdownItemViewInfo> mViewInfoList; @@ -153,6 +149,9 @@ private boolean mEnableDeferredKeyboardPopup; private boolean mPendingKeyboardShowDecision; + private ActivityTabProvider mActivityTabProvider; + private Supplier<ShareDelegate> mShareDelegateSupplier; + @IntDef({SuggestionVisibilityState.DISALLOWED, SuggestionVisibilityState.PENDING_ALLOW, SuggestionVisibilityState.ALLOWED}) @Retention(RetentionPolicy.SOURCE) @@ -228,9 +227,13 @@ void initDefaultProcessors(Callback<List<QueryTile>> queryTileSuggestionCallback) { final Supplier<ImageFetcher> imageFetcherSupplier = createImageFetcherSupplier(); final Supplier<LargeIconBridge> iconBridgeSupplier = createIconBridgeSupplier(); + final Supplier<Tab> tabSupplier = + () -> mActivityTabProvider == null ? null : mActivityTabProvider.get(); + final Supplier<ShareDelegate> shareDelegateSupplier = + () -> mShareDelegateSupplier == null ? null : mShareDelegateSupplier.get(); - mEditUrlProcessor = - new EditUrlSuggestionProcessor(mContext, this, mDelegate, iconBridgeSupplier); + registerSuggestionProcessor(new EditUrlSuggestionProcessor( + mContext, this, mDelegate, iconBridgeSupplier, tabSupplier, shareDelegateSupplier)); registerSuggestionProcessor(new AnswerSuggestionProcessor( mContext, this, mUrlBarEditingTextProvider, imageFetcherSupplier)); registerSuggestionProcessor( @@ -506,14 +509,13 @@ for (SuggestionProcessor processor : mSuggestionProcessors) { processor.onNativeInitialized(); } - if (mEditUrlProcessor != null) mEditUrlProcessor.onNativeInitialized(); } /** * @param provider A means of accessing the activity tab. */ void setActivityTabProvider(ActivityTabProvider provider) { - if (mEditUrlProcessor != null) mEditUrlProcessor.setActivityTabProvider(provider); + mActivityTabProvider = provider; if (mTabObserver != null) { mTabObserver.destroy(); @@ -548,7 +550,7 @@ } void setShareDelegateSupplier(Supplier<ShareDelegate> shareDelegateSupplier) { - mEditUrlProcessor.setShareDelegateSupplier(shareDelegateSupplier); + mShareDelegateSupplier = shareDelegateSupplier; } /** @see org.chromium.chrome.browser.omnibox.UrlFocusChangeListener#onUrlFocusChange(boolean) */ @@ -586,7 +588,6 @@ if (mImageFetcher != null) mImageFetcher.clear(); } - if (mEditUrlProcessor != null) mEditUrlProcessor.onUrlFocusChange(hasFocus); for (SuggestionProcessor processor : mSuggestionProcessors) { processor.onUrlFocusChange(hasFocus); } @@ -938,15 +939,9 @@ * @param suggestion The suggestion to be processed. * @return The appropriate suggestion processor for the provided suggestion. */ - private SuggestionProcessor getProcessorForSuggestion( - OmniboxSuggestion suggestion, boolean isFirst) { - if (isFirst && mEditUrlProcessor != null - && mEditUrlProcessor.doesProcessSuggestion(suggestion)) { - return mEditUrlProcessor; - } - + private SuggestionProcessor getProcessorForSuggestion(OmniboxSuggestion suggestion, int index) { for (SuggestionProcessor processor : mSuggestionProcessors) { - if (processor.doesProcessSuggestion(suggestion)) return processor; + if (processor.doesProcessSuggestion(suggestion, index)) return processor; } assert false : "No default handler for suggestions"; return null; @@ -1145,7 +1140,7 @@ mViewInfoList.add(new DropdownItemViewInfo(mHeaderProcessor, model, currentGroup)); } - final SuggestionProcessor processor = getProcessorForSuggestion(suggestion, index == 0); + final SuggestionProcessor processor = getProcessorForSuggestion(suggestion, index); final PropertyModel model = processor.createModel(); processor.populateModel(suggestion, model, index); mViewInfoList.add(new DropdownItemViewInfo(processor, model, currentGroup));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemProcessor.java index ee59f16..e271b6a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemProcessor.java
@@ -21,29 +21,29 @@ int getMinimumViewHeight(); /** - * @see org.chromium.chrome.browser.omnibox.UrlFocusChangeListener#onUrlFocusChange(boolean) - */ - void onUrlFocusChange(boolean hasFocus); - - /** - * Signals that native initialization has completed. - */ - void onNativeInitialized(); - - /** * Create a model for views managed by the processor. * @return A newly created model. */ PropertyModel createModel(); /** + * @see org.chromium.chrome.browser.omnibox.UrlFocusChangeListener#onUrlFocusChange(boolean) + */ + default void onUrlFocusChange(boolean hasFocus) {} + + /** + * Signals that native initialization has completed. + */ + default void onNativeInitialized() {} + + /** * Record suggestion impressions for this processor. * Purpose of this function is bookkeeping of presented views at the time user finishes * interacting with omnibox (whether navigating somewhere, turning off screen, leaving omnibox * or closing the app). * This call is invoked once for every model created by the processor. */ - void recordItemPresented(PropertyModel model); + default void recordItemPresented(PropertyModel model) {} /** * Record suggestion usage for this processor. @@ -51,10 +51,10 @@ * this processor. * This call is invoked once for every model created by the processor. */ - void recordItemUsed(PropertyModel model); + default void recordItemUsed(PropertyModel model) {} /** * Signals that the dropdown list is about to be populated with new content. */ - void onSuggestionsReceived(); + default void onSuggestionsReceived() {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java index c37d7643f..a304f301 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionProcessor.java
@@ -13,9 +13,10 @@ public interface SuggestionProcessor extends DropdownItemProcessor { /** * @param suggestion The suggestion to process. - * @return Whether this suggestion processor handles this type of suggestion. + * @param position The position of the suggestion in the list. + * @return Whether this suggestion processor handles this type of suggestion at this position. */ - boolean doesProcessSuggestion(OmniboxSuggestion suggestion); + boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position); /** * Populate a model for the given suggestion.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java index 5f5f619..2350374 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
@@ -54,7 +54,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { // Calculation answers are specific in a way that these are basic suggestions, but processed // as answers, when new answer layout is enabled. return suggestion.hasAnswer() || suggestion.getType() == OmniboxSuggestionType.CALCULATOR;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java index b91f3f0..229d54d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewProcessor.java
@@ -54,14 +54,12 @@ R.dimen.omnibox_suggestion_comfortable_height); } - @Override - public void onUrlFocusChange(boolean hasFocus) {} - - @Override - public void recordItemPresented(PropertyModel model) {} - - @Override - public void recordItemUsed(PropertyModel model) {} + /** + * @return The desired size of Omnibox suggestion favicon. + */ + protected int getDesiredFaviconSize() { + return mDesiredFaviconWidthPx; + } @Override public void onNativeInitialized() { @@ -80,9 +78,6 @@ } @Override - public void onSuggestionsReceived() {} - - @Override public int getMinimumViewHeight() { return mSuggestionSizePx; }
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 383f0c61..20a3e09 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
@@ -52,7 +52,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessor.java index 03fb31a..7b443233 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessor.java
@@ -39,7 +39,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { return suggestion.getType() == OmniboxSuggestionType.CLIPBOARD_URL || suggestion.getType() == OmniboxSuggestionType.CLIPBOARD_TEXT || suggestion.getType() == OmniboxSuggestionType.CLIPBOARD_IMAGE; @@ -73,6 +73,18 @@ if (imageData != null && imageData.length > 0) { Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length); if (bitmap != null) { + // TODO(crbug.com/1090919): This is short term solution, resize need to be + // handled somewhere else. + if (bitmap.getWidth() > 0 && bitmap.getHeight() > 0 + && (bitmap.getWidth() > getDesiredFaviconSize() + || bitmap.getHeight() > getDesiredFaviconSize())) { + float max = Math.max(bitmap.getWidth(), bitmap.getHeight()); + float scale = (float) getDesiredFaviconSize() / max; + float width = bitmap.getWidth(); + float height = bitmap.getHeight(); + bitmap = Bitmap.createScaledBitmap(bitmap, (int) Math.round(scale * width), + (int) Math.round(scale * height), true); + } setSuggestionDrawableState(model, SuggestionDrawableState.Builder.forBitmap(getContext(), bitmap) .build());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java index 6bc50e6b..777d120 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionProcessor.java
@@ -10,7 +10,6 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; -import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionUiType; @@ -45,10 +44,10 @@ private final Supplier<LargeIconBridge> mIconBridgeSupplier; /** The delegate for accessing the sharing feature. */ - private Supplier<ShareDelegate> mShareDelegateSupplier; + private final Supplier<ShareDelegate> mShareDelegateSupplier; /** A means of accessing the activity's tab. */ - private ActivityTabProvider mTabProvider; + private final Supplier<Tab> mTabSupplier; /** Whether the omnibox has already cleared its content for the focus event. */ private boolean mHasClearedOmniboxForFocus; @@ -63,16 +62,21 @@ * @param locationBarDelegate A means of modifying the location bar. */ public EditUrlSuggestionProcessor(Context context, SuggestionHost suggestionHost, - UrlBarDelegate locationBarDelegate, Supplier<LargeIconBridge> iconBridgeSupplier) { + UrlBarDelegate locationBarDelegate, Supplier<LargeIconBridge> iconBridgeSupplier, + Supplier<Tab> tabSupplier, Supplier<ShareDelegate> shareDelegateSupplier) { super(context, suggestionHost); mUrlBarDelegate = locationBarDelegate; mIconBridgeSupplier = iconBridgeSupplier; + mTabSupplier = tabSupplier; + mShareDelegateSupplier = shareDelegateSupplier; } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { - Tab activeTab = mTabProvider != null ? mTabProvider.get() : null; + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { + if (position != 0) return false; + + Tab activeTab = mTabSupplier.get(); // The what-you-typed suggestion can potentially appear as the second suggestion in some // cases. If the first suggestion isn't the one we want, ignore all subsequent suggestions. if (activeTab == null || activeTab.isNativePage() || activeTab.isIncognito() @@ -107,7 +111,10 @@ public void populateModel(OmniboxSuggestion suggestion, PropertyModel model, int position) { super.populateModel(suggestion, model, position); - if (mOriginalTitle == null) mOriginalTitle = mTabProvider.get().getTitle(); + if (mOriginalTitle == null) { + mOriginalTitle = mTabSupplier.get().getTitle(); + } + model.set( SuggestionViewProperties.TEXT_LINE_1_TEXT, new SuggestionSpannable(mOriginalTitle)); model.set(SuggestionViewProperties.TEXT_LINE_2_TEXT, @@ -151,20 +158,6 @@ RecordUserAction.record("Omnibox.EditUrlSuggestion.Tap"); } - /** - * @param provider A means of accessing the activity's tab. - */ - public void setActivityTabProvider(ActivityTabProvider provider) { - mTabProvider = provider; - } - - /** - * @param shareDelegateSupplier A means of accessing the sharing feature. - */ - public void setShareDelegateSupplier(Supplier<ShareDelegate> shareDelegateSupplier) { - mShareDelegateSupplier = shareDelegateSupplier; - } - @Override public void onUrlFocusChange(boolean hasFocus) { if (hasFocus) return; @@ -177,7 +170,7 @@ RecordUserAction.record("Omnibox.EditUrlSuggestion.Share"); mUrlBarDelegate.clearOmniboxFocus(); // TODO(mdjones): This should only share the displayed URL instead of the background tab. - Tab activityTab = mTabProvider.get(); + Tab activityTab = mTabSupplier.get(); mShareDelegateSupplier.get().share(activityTab, false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java index ebe976c..798cad1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/entity/EntitySuggestionProcessor.java
@@ -74,7 +74,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { return suggestion.getType() == OmniboxSuggestionType.SEARCH_SUGGEST_ENTITY; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderProcessor.java index 947ede8..c44cd754 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/header/HeaderProcessor.java
@@ -41,25 +41,10 @@ } @Override - public void onUrlFocusChange(boolean hasFocus) {} - - @Override - public void onNativeInitialized() {} - - @Override public PropertyModel createModel() { return new PropertyModel(HeaderViewProperties.ALL_KEYS); } - @Override - public void recordItemPresented(PropertyModel model) {} - - @Override - public void recordItemUsed(PropertyModel model) {} - - @Override - public void onSuggestionsReceived() {} - /** * Populate a model for the group header. * @param model The model to populate.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionProcessor.java index b3df7b6..d92aed42 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tail/TailSuggestionProcessor.java
@@ -32,7 +32,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { return mAlignTailSuggestions && suggestion.getType() == OmniboxSuggestionType.SEARCH_SUGGEST_TAIL; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tiles/TileSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tiles/TileSuggestionProcessor.java index e123130..59c7383 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tiles/TileSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/tiles/TileSuggestionProcessor.java
@@ -36,7 +36,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { return suggestion.getType() == OmniboxSuggestionType.TILE_SUGGESTION; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProvider.java index 3440c17..ec9c22ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProvider.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController.SheetState; import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetObserver; import org.chromium.chrome.browser.widget.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.components.browser_ui.share.ShareParams; import org.chromium.printing.PrintManagerDelegateImpl; import org.chromium.printing.PrintingController; import org.chromium.printing.PrintingControllerImpl; @@ -55,6 +56,7 @@ private final BottomSheetController mBottomSheetController; private final ShareSheetBottomSheetContent mBottomSheetContent; private final PrefServiceBridge mPrefServiceBridge; + private final ShareParams mShareParams; private final long mShareStartTime; private ScreenshotCoordinator mScreenshotCoordinator; private Map<Integer, Set<Integer>> mSharingOptionToContentTypes; @@ -65,21 +67,23 @@ * @param activity The current {@link Activity}. * @param tabProvider Supplier for the current activity tab. * @param bottomSheetController The {@link BottomSheetController} for the current activity. - * @param bottomSheetContent The {@link ShareSheetBottomSheetContent} for the current - * activity. - * @param prefServiceBridge The {@link PrefServiceBridge} singleton. This provides printing - * preferences. - * @param shareStartTime The start time of the current share. + * @param bottomSheetContent The {@link ShareSheetBottomSheetContent} for the current + * activity. + * @param prefServiceBridge The {@link PrefServiceBridge} singleton. This provides printing + * preferences. + * @param shareParams The {@link ShareParams} for the current share. + * @param shareStartTime The start time of the current share. */ ChromeProvidedSharingOptionsProvider(Activity activity, Supplier<Tab> tabProvider, BottomSheetController bottomSheetController, ShareSheetBottomSheetContent bottomSheetContent, PrefServiceBridge prefServiceBridge, - long shareStartTime) { + ShareParams shareParams, long shareStartTime) { mActivity = activity; mTabProvider = tabProvider; mBottomSheetController = bottomSheetController; mBottomSheetContent = bottomSheetContent; mPrefServiceBridge = prefServiceBridge; + mShareParams = shareParams; mShareStartTime = shareStartTime; mSharingOptionToContentTypes = createSharingOptionToContentTypesMap(); } @@ -186,19 +190,10 @@ "Sharing.SharingHubAndroid.TimeToShare", System.currentTimeMillis() - mShareStartTime); mBottomSheetController.hideContent(mBottomSheetContent, true); - Tab tab = mTabProvider.get(); - String title = tab.getWebContents() - .getNavigationController() - .getVisibleEntry() - .getTitle(); - String url = tab.getWebContents() - .getNavigationController() - .getVisibleEntry() - .getUrl(); ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService( Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText(title, url); - clipboard.setPrimaryClip(clip); + clipboard.setPrimaryClip( + ClipData.newPlainText(mShareParams.getTitle(), mShareParams.getUrl())); Toast toast = Toast.makeText(mActivity, R.string.link_copied, Toast.LENGTH_SHORT); toast.show();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java index fcd8c86..9a58aa7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareSheetCoordinator.java
@@ -65,7 +65,8 @@ ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity); mShareStartTime = shareStartTime; - List<PropertyModel> chromeFeatures = createTopRowPropertyModels(bottomSheet, activity); + List<PropertyModel> chromeFeatures = + createTopRowPropertyModels(bottomSheet, activity, params); List<PropertyModel> thirdPartyApps = createBottomRowPropertyModels(bottomSheet, activity, params, saveLastUsed); @@ -87,13 +88,14 @@ } List<PropertyModel> createTopRowPropertyModels( - ShareSheetBottomSheetContent bottomSheet, Activity activity) { + ShareSheetBottomSheetContent bottomSheet, Activity activity, ShareParams shareParams) { if (mExcludeFirstParty) { return new ArrayList<>(); } ChromeProvidedSharingOptionsProvider chromeProvidedSharingOptionsProvider = new ChromeProvidedSharingOptionsProvider(activity, mTabProvider, - mBottomSheetController, bottomSheet, mPrefServiceBridge, mShareStartTime); + mBottomSheetController, bottomSheet, mPrefServiceBridge, shareParams, + mShareStartTime); return chromeProvidedSharingOptionsProvider.createPropertyModels(new HashSet<>( Arrays.asList(ContentType.LINK_PAGE_VISIBLE, ContentType.LINK_PAGE_NOT_VISIBLE, ContentType.TEXT, ContentType.IMAGE, ContentType.OTHER_FILE_TYPE)));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderTest.java index 6981fbe..56c6adf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderTest.java
@@ -65,7 +65,7 @@ mChromeProvidedSharingOptionsProvider = new ChromeProvidedSharingOptionsProvider(mActivity, /*activityTabProvider=*/null, /*bottomSheetController=*/null, new ShareSheetBottomSheetContent(mActivity), mPrefServiceBridge, - /*shareStartTime=*/0); + /*shareParams=*/null, /*shareStartTime=*/0); // Return false to indicate printing is disabled. Mockito.when(mPrefServiceBridge.getBoolean(anyInt())).thenReturn(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareSheetCoordinatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareSheetCoordinatorTest.java index 01c8551..868d14c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareSheetCoordinatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/share/ShareSheetCoordinatorTest.java
@@ -84,7 +84,7 @@ ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity); List<PropertyModel> propertyModels = - coordinator.createTopRowPropertyModels(bottomSheet, activity); + coordinator.createTopRowPropertyModels(bottomSheet, activity, /*shareParams=*/null); Assert.assertEquals("Property model list should be empty.", 0, propertyModels.size()); }
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java index a1cdb7d7..26c91ce 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediatorUnitTest.java
@@ -94,7 +94,7 @@ mMediator.setSuggestionVisibilityState( AutocompleteMediator.SuggestionVisibilityState.ALLOWED); - when(mMockProcessor.doesProcessSuggestion(any())).thenReturn(true); + when(mMockProcessor.doesProcessSuggestion(any(), anyInt())).thenReturn(true); when(mMockProcessor.createModel()) .thenAnswer((mock) -> new PropertyModel(SuggestionCommonProperties.ALL_KEYS)); when(mMockProcessor.getMinimumViewHeight()).thenReturn(SUGGESTION_MIN_HEIGHT);
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionProcessorTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionProcessorTest.java index ad6f1e87..8e7f7475f 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionProcessorTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionProcessorTest.java
@@ -53,7 +53,7 @@ } @Override - public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { + public boolean doesProcessSuggestion(OmniboxSuggestion suggestion, int position) { return true; }
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessorTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessorTest.java index 8fb51d9..b83be74 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessorTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/clipboard/ClipboardSuggestionProcessorTest.java
@@ -197,4 +197,22 @@ Assert.assertEquals( mBitmap.getHeight(), ((BitmapDrawable) icon.drawable).getBitmap().getHeight()); } + + @CalledByNativeJavaTest + public void clipboardSuggestion_thumbnailShouldResizeIfTooLarge() { + int size = ContextUtils.getApplicationContext().getResources().getDimensionPixelSize( + R.dimen.omnibox_suggestion_favicon_size); + + Bitmap largeBitmap = Bitmap.createBitmap(size * 2, size * 2, Config.ARGB_8888); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Assert.assertTrue(largeBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos)); + byte[] bitmapData = baos.toByteArray(); + createClipboardSuggestion( + OmniboxSuggestionType.CLIPBOARD_IMAGE, GURL.emptyGURL(), bitmapData); + SuggestionDrawableState icon = mModel.get(BaseSuggestionViewProperties.ICON); + Assert.assertNotNull(icon); + + Assert.assertEquals(size, ((BitmapDrawable) icon.drawable).getBitmap().getWidth()); + Assert.assertEquals(size, ((BitmapDrawable) icon.drawable).getBitmap().getHeight()); + } }
diff --git a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java index 8b8a4135..fce432e62 100644 --- a/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java +++ b/chrome/android/native_java_unittests/src/org/chromium/chrome/browser/omnibox/suggestions/editurl/EditUrlSuggestionUnitTest.java
@@ -19,7 +19,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNativeJavaTest; -import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion; import org.chromium.chrome.browser.omnibox.suggestions.UrlBarDelegate; @@ -58,9 +57,6 @@ private PropertyModel mModel; @Mock - private ActivityTabProvider mTabProvider; - - @Mock private ShareDelegate mShareDelegate; @Mock @@ -107,8 +103,6 @@ when(mTab.isNativePage()).thenReturn(false); when(mTab.isIncognito()).thenReturn(false); - when(mTabProvider.get()).thenReturn(mTab); - when(mWhatYouTypedSuggestion.getType()) .thenReturn(OmniboxSuggestionType.URL_WHAT_YOU_TYPED); when(mWhatYouTypedSuggestion.getUrl()).thenReturn(mTestUrl); @@ -122,10 +116,8 @@ mModel = new PropertyModel.Builder(SuggestionViewProperties.ALL_KEYS).build(); mProcessor = new EditUrlSuggestionProcessor(ContextUtils.getApplicationContext(), - mSuggestionHost, mUrlBarDelegate, () -> mIconBridge); - - mProcessor.setActivityTabProvider(mTabProvider); - mProcessor.setShareDelegateSupplier(() -> mShareDelegate); + mSuggestionHost, mUrlBarDelegate, + () -> mIconBridge, () -> mTab, () -> mShareDelegate); } /** Test that the suggestion is triggered. */ @@ -134,7 +126,7 @@ mProcessor.onUrlFocusChange(true); Assert.assertTrue("The processor should handle the \"what you typed\" suggestion.", - mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion)); + mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion, 0)); mProcessor.populateModel(mWhatYouTypedSuggestion, mModel, 0); @@ -153,14 +145,14 @@ when(mWhatYouTypedSuggestion.getUrl()).thenReturn(mFoobarSearchUrl); Assert.assertFalse("The processor should not handle the suggestion.", - mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion)); + mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion, 0)); } /** Test the edit button is pressed, the correct method in the URL bar delegate is triggered. */ @CalledByNativeJavaTest public void testEditButtonPress() { mProcessor.onUrlFocusChange(true); - mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion); + mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion, 0); mProcessor.populateModel(mWhatYouTypedSuggestion, mModel, 0); List<Action> actions = mModel.get(BaseSuggestionViewProperties.ACTIONS); @@ -173,7 +165,7 @@ @CalledByNativeJavaTest public void testShareButtonPress() { mProcessor.onUrlFocusChange(true); - mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion); + mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion, 0); mProcessor.populateModel(mWhatYouTypedSuggestion, mModel, 0); List<Action> actions = mModel.get(BaseSuggestionViewProperties.ACTIONS); @@ -186,7 +178,7 @@ @CalledByNativeJavaTest public void testCopyButtonPress() { mProcessor.onUrlFocusChange(true); - mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion); + mProcessor.doesProcessSuggestion(mWhatYouTypedSuggestion, 0); mProcessor.populateModel(mWhatYouTypedSuggestion, mModel, 0); List<Action> actions = mModel.get(BaseSuggestionViewProperties.ACTIONS); @@ -210,11 +202,13 @@ when(mTemplateUrlService.getSearchQueryForUrl(mBarbazSearchUrl)) .thenReturn(BARBAZ_SEARCH_TERMS); - Assert.assertTrue(mProcessor.doesProcessSuggestion(mSearchSuggestion)); + Assert.assertTrue(mProcessor.doesProcessSuggestion(mSearchSuggestion, 0)); + Assert.assertFalse(mProcessor.doesProcessSuggestion(mSearchSuggestion, 1)); when(mSearchSuggestion.getUrl()).thenReturn(mBarbazSearchUrl); when(mSearchSuggestion.getFillIntoEdit()).thenReturn(BARBAZ_SEARCH_TERMS); - Assert.assertFalse(mProcessor.doesProcessSuggestion(mSearchSuggestion)); + Assert.assertFalse(mProcessor.doesProcessSuggestion(mSearchSuggestion, 0)); + Assert.assertFalse(mProcessor.doesProcessSuggestion(mSearchSuggestion, 1)); } }
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 2948bfa2f..7d10296d6 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -227,6 +227,7 @@ if (is_chromeos) { deps += [ + "//chrome/browser/chromeos/net/network_health/public/mojom", "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings", "//chrome/browser/ui/webui/chromeos/crostini_installer:mojo_bindings", "//chrome/browser/ui/webui/chromeos/crostini_upgrader:mojo_bindings",
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index cfbbc46e..3c3245e 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3379,6 +3379,9 @@ <message name="IDS_NETWORK_UI_GLOBAL_POLICY" desc="Label for global policy properties"> Global Policy: </message> + <message name="IDS_NETWORK_UI_NETWORK_HEALTH" desc="Label for network health section"> + Network Health Snapshot + </message> <message name="IDS_NETWORK_UI_NETWORK_LISTS" desc="Label for network lists section"> Network (Service) and Device properties </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 9c9e3d5..d3bfb88 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -295,6 +295,22 @@ <message name="IDS_SETTINGS_PASSWORDS" desc="Name for the password section and settings entry used for managing passwords."> Passwords </message> + <!-- TODO(crbug.com/1062344): Make it translateable once final strings are available. Also add screenshot file. --> + <message name="IDS_SETTINGS_DEVICE_PASSWORDS" translateable="false" desc="Name for the passwords section used for managing passwords/exceptions stored on the device."> + Passwords on this device + </message> + <!-- TODO(crbug.com/1062344): Make it translateable once final strings are available. Also add screenshot file. --> + <message name="IDS_SETTINGS_DEVICE_PASSWORDS_EMPTY_SUBSECTION_TEXT" translateable="false" desc="Fallback text displayed under a subsection of the 'device passwords' page, in case that subsection is empty."> + No passwords + </message> + <!-- TODO(crbug.com/1062344): Make it translateable once final strings are available. Also add screenshot file. --> + <message name="IDS_SETTINGS_DEVICE_PASSWORDS_ON_DEVICE_ONLY_HEADING" translateable="false" desc="Title of a subsection in the 'device passwords' page displaying passwords/exceptions that are stored only on the device."> + On this device only + </message> + <!-- TODO(crbug.com/1062344): Make it translateable once final strings are available. Also add screenshot file. --> + <message name="IDS_SETTINGS_DEVICE_PASSWORDS_ON_DEVICE_AND_ACCOUNT_HEADING" translateable="false" desc="Title of a subsection in the 'device passwords' page displaying passwords/exceptions that are stored both on the device and in the account."> + On this device and in your Google Account + </message> <message name="IDS_SETTINGS_CHECK_PASSWORDS" desc="Name for the check passwords subsection and settings entry used to perform a password bulk check."> Check passwords </message>
diff --git a/chrome/browser/android/browsing_data/browsing_data_bridge.cc b/chrome/browser/android/browsing_data/browsing_data_bridge.cc index 5fa2c28..d019e8b0 100644 --- a/chrome/browser/android/browsing_data/browsing_data_bridge.cc +++ b/chrome/browser/android/browsing_data/browsing_data_bridge.cc
@@ -94,7 +94,7 @@ std::vector<int> data_types_vector; base::android::JavaIntArrayToIntVector(env, data_types, &data_types_vector); - int remove_mask = 0; + uint64_t remove_mask = 0; for (const int data_type : data_types_vector) { switch (static_cast<browsing_data::BrowsingDataType>(data_type)) { case browsing_data::BrowsingDataType::HISTORY:
diff --git a/chrome/browser/android/tab_web_contents_delegate_android.cc b/chrome/browser/android/tab_web_contents_delegate_android.cc index f3997db..ad17313 100644 --- a/chrome/browser/android/tab_web_contents_delegate_android.cc +++ b/chrome/browser/android/tab_web_contents_delegate_android.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/android/hung_renderer_infobar_delegate.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/banners/app_banner_manager_android.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/content_settings/sound_content_setting_observer.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_tab_helper.h" #include "chrome/browser/file_select_helper.h" @@ -43,7 +44,7 @@ #include "chrome/browser/ui/android/sms/sms_infobar.h" #include "chrome/browser/ui/android/tab_model/tab_model_list.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" +#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/interventions/framebust_block_message_delegate.h" #include "chrome/browser/ui/prefs/prefs_tab_helper.h" @@ -51,6 +52,7 @@ #include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" +#include "components/blocked_content/popup_blocker.h" #include "components/blocked_content/popup_tracker.h" #include "components/browser_ui/util/android/url_constants.h" #include "components/find_in_page/find_notification_details.h" @@ -355,16 +357,25 @@ nav_params.FillNavigateParamsFromOpenURLParams(params); nav_params.source_contents = source; nav_params.window_action = NavigateParams::SHOW_WINDOW; - if (ConsiderForPopupBlocking(params.disposition) && - MaybeBlockPopup(source, nullptr, &nav_params, ¶ms, - blink::mojom::WindowFeatures())) { - return nullptr; + auto popup_delegate = + std::make_unique<ChromePopupNavigationDelegate>(std::move(nav_params)); + if (blocked_content::ConsiderForPopupBlocking(params.disposition)) { + popup_delegate.reset(static_cast<ChromePopupNavigationDelegate*>( + blocked_content::MaybeBlockPopup( + source, nullptr, std::move(popup_delegate), ¶ms, + blink::mojom::WindowFeatures(), + HostContentSettingsMapFactory::GetForProfile( + source->GetBrowserContext())) + .release())); + if (!popup_delegate) + return nullptr; } if (disposition == WindowOpenDisposition::CURRENT_TAB) { // Only prerender for a current-tab navigation to avoid session storage // namespace issues. - prerender::PrerenderManager::Params prerender_params(&nav_params, source); + prerender::PrerenderManager::Params prerender_params( + popup_delegate->nav_params(), source); prerender::PrerenderManager* prerender_manager = prerender::PrerenderManagerFactory::GetForBrowserContext(profile); if (prerender_manager && prerender_manager->MaybeUsePrerenderedPage( @@ -376,8 +387,8 @@ return WebContentsDelegateAndroid::OpenURLFromTab(source, params); } - nav_params.created_with_opener = true; - TabModelList::HandlePopupNavigation(&nav_params); + popup_delegate->nav_params()->created_with_opener = true; + TabModelList::HandlePopupNavigation(popup_delegate->nav_params()); return nullptr; } @@ -406,7 +417,7 @@ // At this point the |new_contents| is beyond the popup blocker, but we use // the same logic for determining if the popup tracker needs to be attached. - if (source && ConsiderForPopupBlocking(disposition)) { + if (source && blocked_content::ConsiderForPopupBlocking(disposition)) { blocked_content::PopupTracker::CreateForWebContents(new_contents.get(), source, disposition); }
diff --git a/chrome/browser/browsing_data/browsing_data_important_sites_util.cc b/chrome/browser/browsing_data/browsing_data_important_sites_util.cc index fdc3182..fe38cb6 100644 --- a/chrome/browser/browsing_data/browsing_data_important_sites_util.cc +++ b/chrome/browser/browsing_data/browsing_data_important_sites_util.cc
@@ -55,8 +55,8 @@ namespace browsing_data_important_sites_util { -void Remove(int remove_mask, - int origin_mask, +void Remove(uint64_t remove_mask, + uint64_t origin_mask, browsing_data::TimePeriod time_period, std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder, content::BrowsingDataRemover* remover, @@ -64,8 +64,8 @@ auto* observer = new BrowsingDataTaskObserver(remover, std::move(callback), 2); - int filterable_mask = 0; - int nonfilterable_mask = remove_mask; + uint64_t filterable_mask = 0; + uint64_t nonfilterable_mask = remove_mask; if (!filter_builder->IsEmptyBlacklist()) { filterable_mask =
diff --git a/chrome/browser/browsing_data/browsing_data_important_sites_util.h b/chrome/browser/browsing_data/browsing_data_important_sites_util.h index 41ac60d..4839ed6 100644 --- a/chrome/browser/browsing_data/browsing_data_important_sites_util.h +++ b/chrome/browser/browsing_data/browsing_data_important_sites_util.h
@@ -18,8 +18,8 @@ // Deletes the types protected by Important Sites with the filter from // |filter_builder|, the other types are deleted completely. // |callback| will be called when the deletion finished. -void Remove(int remove_mask, - int origin_mask, +void Remove(uint64_t remove_mask, + uint64_t origin_mask, browsing_data::TimePeriod time_period, std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder, content::BrowsingDataRemover* remover,
diff --git a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc index b2596b5..bb7b4df 100644 --- a/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc +++ b/chrome/browser/browsing_data/browsing_data_remover_browsertest.cc
@@ -357,15 +357,15 @@ VerifyDownloadCount(1u); } - void RemoveAndWait(int remove_mask) { + void RemoveAndWait(uint64_t remove_mask) { RemoveAndWait(remove_mask, base::Time(), base::Time::Max()); } - void RemoveAndWait(int remove_mask, base::Time delete_begin) { + void RemoveAndWait(uint64_t remove_mask, base::Time delete_begin) { RemoveAndWait(remove_mask, delete_begin, base::Time::Max()); } - void RemoveAndWait(int remove_mask, + void RemoveAndWait(uint64_t remove_mask, base::Time delete_begin, base::Time delete_end) { content::BrowsingDataRemover* remover = @@ -380,7 +380,7 @@ } void RemoveWithFilterAndWait( - int remove_mask, + uint64_t remove_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) { content::BrowsingDataRemover* remover = content::BrowserContext::GetBrowsingDataRemover(
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index a0619e2..0e80522c 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -240,11 +240,11 @@ #endif // Returned by ChromeBrowsingDataRemoverDelegate::GetOriginTypeMatcher(). -bool DoesOriginMatchEmbedderMask(int origin_type_mask, +bool DoesOriginMatchEmbedderMask(uint64_t origin_type_mask, const url::Origin& origin, storage::SpecialStoragePolicy* policy) { DCHECK_EQ( - 0, + 0ULL, origin_type_mask & (ChromeBrowsingDataRemoverDelegate::ORIGIN_TYPE_EMBEDDER_BEGIN - 1)) << "|origin_type_mask| can only contain origin types defined in " @@ -326,9 +326,9 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask, + uint64_t origin_type_mask, base::OnceClosure callback) { DCHECK(((remove_mask & ~content::BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS &
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h index e73438b..e6bb4ffe 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
@@ -56,9 +56,7 @@ public: // This is an extension of content::BrowsingDataRemover::RemoveDataMask which // includes all datatypes therefrom and adds additional Chrome-specific ones. - // TODO(crbug.com/668114): Extend this to uint64_t to ensure that we won't - // run out of space anytime soon. - enum DataType { + enum DataType : uint64_t { // Embedder can start adding datatypes after the last platform datatype. DATA_TYPE_EMBEDDER_BEGIN = content::BrowsingDataRemover::DATA_TYPE_CONTENT_END << 1, @@ -128,7 +126,7 @@ // This is an extension of content::BrowsingDataRemover::OriginType which // includes all origin types therefrom and adds additional Chrome-specific // ones. - enum OriginType { + enum OriginType : uint64_t { // Embedder can start adding origin types after the last // platform origin type. ORIGIN_TYPE_EMBEDDER_BEGIN = @@ -166,9 +164,9 @@ bool MayRemoveDownloadHistory() override; void RemoveEmbedderData(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, content::BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask, + uint64_t origin_type_mask, base::OnceClosure callback) override; #if defined(OS_ANDROID)
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 2e08bc8..7fab9db 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -189,10 +189,12 @@ // Shorthands for origin types. #if BUILDFLAG(ENABLE_EXTENSIONS) -const int kExtension = ChromeBrowsingDataRemoverDelegate::ORIGIN_TYPE_EXTENSION; +const uint64_t kExtension = + ChromeBrowsingDataRemoverDelegate::ORIGIN_TYPE_EXTENSION; #endif -const int kProtected = content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; -const int kUnprotected = +const uint64_t kProtected = + content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; +const uint64_t kUnprotected = content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; // TODO(https://crbug.com/1042727): Fix test GURL scoping and remove this getter @@ -930,7 +932,7 @@ NOTREACHED(); } - void RemoveBrowsingData(int data_type_mask, + void RemoveBrowsingData(uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override { ++remove_calls_; @@ -938,7 +940,7 @@ last_origin_filter_ = origin_filter; } - void RemoveAllBrowsingData(int data_type_mask) override { + void RemoveAllBrowsingData(uint64_t data_type_mask) override { ++remove_all_calls_; last_data_type_mask_ = data_type_mask; last_origin_filter_ = base::RepeatingCallback<bool(const GURL&)>(); @@ -959,7 +961,7 @@ int remove_calls() const { return remove_calls_; } int remove_all_calls() const { return remove_all_calls_; } - int last_data_type_mask() const { return last_data_type_mask_; } + uint64_t last_data_type_mask() const { return last_data_type_mask_; } const base::RepeatingCallback<bool(const GURL&)>& last_origin_filter() const { return last_origin_filter_; } @@ -967,7 +969,7 @@ private: int remove_calls_ = 0; int remove_all_calls_ = 0; - int last_data_type_mask_ = 0; + uint64_t last_data_type_mask_ = 0; base::RepeatingCallback<bool(const GURL&)> last_origin_filter_; DISALLOW_COPY_AND_ASSIGN(MockReportingService); @@ -1172,9 +1174,9 @@ void BlockUntilBrowsingDataRemoved(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, bool include_protected_origins) { - int origin_type_mask = + uint64_t origin_type_mask = content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; if (include_protected_origins) { origin_type_mask |= @@ -1193,7 +1195,7 @@ void BlockUntilOriginDataRemoved( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) { content::BrowsingDataRemoverCompletionObserver completion_observer( remover_); @@ -1209,9 +1211,11 @@ return remover_->GetLastUsedBeginTimeForTesting(); } - int GetRemovalMask() { return remover_->GetLastUsedRemovalMaskForTesting(); } + uint64_t GetRemovalMask() { + return remover_->GetLastUsedRemovalMaskForTesting(); + } - int GetOriginTypeMask() { + uint64_t GetOriginTypeMask() { return remover_->GetLastUsedOriginTypeMaskForTesting(); } @@ -1222,7 +1226,7 @@ } bool Match(const GURL& origin, - int mask, + uint64_t mask, storage::SpecialStoragePolicy* policy) { return remover_->DoesOriginMatchMaskForTesting( mask, url::Origin::Create(origin), policy); @@ -1429,8 +1433,9 @@ RemovePasswordsTester tester(GetProfile()); EXPECT_CALL(*tester.store(), RemoveLoginsByURLAndTimeImpl(_, _, _)); - int removal_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY | - ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS; + uint64_t removal_mask = + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY | + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS; BlockUntilBrowsingDataRemoved(AnHourAgo(), base::Time::Max(), removal_mask, false); @@ -2963,9 +2968,9 @@ } // Delete all data types that trigger website setting deletions. - int mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY | - ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA | - ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS; + uint64_t mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY | + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA | + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_CONTENT_SETTINGS; BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), mask, false);
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 82c45dc..e250881 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -121,6 +121,7 @@ #endif #if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom.h" #include "chrome/browser/ui/webui/app_management/app_management.mojom.h" #include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision.mojom.h" #include "chrome/browser/ui/webui/chromeos/add_supervision/add_supervision_ui.h" @@ -549,7 +550,11 @@ RegisterWebUIControllerInterfaceBinder< media_app_ui::mojom::PageHandlerFactory, chromeos::MediaAppUI>(map); -#endif + + RegisterWebUIControllerInterfaceBinder< + chromeos::network_health::mojom::NetworkHealthService, + chromeos::NetworkUI>(map); +#endif // defined(OS_CHROMEOS) #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) || \ defined(OS_CHROMEOS)
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index f1feb88..aea13f5 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -139,7 +139,7 @@ #include "chrome/browser/tracing/chrome_tracing_delegate.h" #include "chrome/browser/translate/translate_service.h" #include "chrome/browser/ui/blocked_content/blocked_window_params.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" +#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h" #include "chrome/browser/ui/blocked_content/tab_under_navigation_throttle.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" @@ -182,6 +182,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/installer/util/google_update_settings.h" #include "components/autofill/core/common/autofill_switches.h" +#include "components/blocked_content/popup_blocker.h" #include "components/browsing_data/content/browsing_data_helper.h" #include "components/browsing_data/core/browsing_data_utils.h" #include "components/captive_portal/content/captive_portal_service.h" @@ -3094,9 +3095,12 @@ target_url, source_origin, opener->GetSiteInstance(), referrer, frame_name, disposition, features, user_gesture, opener_suppressed); NavigateParams nav_params = blocked_params.CreateNavigateParams(web_contents); - return !MaybeBlockPopup(web_contents, &opener_top_level_frame_url, - &nav_params, nullptr /*=open_url_params*/, - blocked_params.features()); + return blocked_content::MaybeBlockPopup( + web_contents, &opener_top_level_frame_url, + std::make_unique<ChromePopupNavigationDelegate>( + std::move(nav_params)), + nullptr /*=open_url_params*/, blocked_params.features(), + HostContentSettingsMapFactory::GetForProfile(profile)) != nullptr; } content::SpeechRecognitionManagerDelegate*
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index c9fda690..e5ae6d8 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -75,7 +75,7 @@ "//chrome/browser/apps/platform_apps", "//chrome/browser/apps/platform_apps/api", "//chrome/browser/chromeos/child_accounts/time_limits/web_time_limit_error_page", - "//chrome/browser/chromeos/net/mojom", + "//chrome/browser/chromeos/net/network_health/public/mojom", "//chrome/browser/chromeos/power/ml/smart_dim", "//chrome/browser/devtools", "//chrome/browser/extensions", @@ -1762,8 +1762,10 @@ "net/network_diagnostics/network_diagnostics_routine.h", "net/network_diagnostics/signal_strength_routine.cc", "net/network_diagnostics/signal_strength_routine.h", - "net/network_health.cc", - "net/network_health.h", + "net/network_health/network_health.cc", + "net/network_health/network_health.h", + "net/network_health/network_health_service.cc", + "net/network_health/network_health_service.h", "net/network_portal_detector_impl.cc", "net/network_portal_detector_impl.h", "net/network_portal_detector_test_impl.cc", @@ -3093,7 +3095,7 @@ "net/network_diagnostics/lan_connectivity_routine_unittest.cc", "net/network_diagnostics/network_diagnostics_routine_unittest.cc", "net/network_diagnostics/signal_strength_routine_unittest.cc", - "net/network_health_unittest.cc", + "net/network_health/network_health_unittest.cc", "net/network_portal_detector_impl_unittest.cc", "net/network_pref_state_observer_unittest.cc", "net/network_throttling_observer_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc index 532f4b4d..cd4da0cb 100644 --- a/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc +++ b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.cc
@@ -73,7 +73,7 @@ } void ArcOemCryptoBridge::OnBootstrapMojoConnection( - mojom::OemCryptoServiceRequest request, + mojo::PendingReceiver<mojom::OemCryptoService> receiver, bool result) { if (!result) { // This can currently happen due to limited device support, so do not log @@ -84,10 +84,11 @@ return; } DVLOG(1) << "ArcOemCryptoBridge succeeded with Mojo bootstrapping."; - ConnectToDaemon(std::move(request)); + ConnectToDaemon(std::move(receiver)); } -void ArcOemCryptoBridge::Connect(mojom::OemCryptoServiceRequest request) { +void ArcOemCryptoBridge::Connect( + mojo::PendingReceiver<mojom::OemCryptoService> receiver) { DVLOG(1) << "ArcOemCryptoBridge::Connect called"; // Check that the user has Attestation for Content Protection enabled in @@ -109,7 +110,7 @@ if (oemcrypto_host_daemon_remote_.is_bound()) { DVLOG(1) << "Re-using bootstrap connection for OemCryptoService Connect"; - ConnectToDaemon(std::move(request)); + ConnectToDaemon(std::move(receiver)); return; } DVLOG(1) << "Bootstrapping the OemCrypto connection via D-Bus"; @@ -139,11 +140,11 @@ ->BootstrapMojoConnection( std::move(fd), base::BindOnce(&ArcOemCryptoBridge::OnBootstrapMojoConnection, - weak_factory_.GetWeakPtr(), std::move(request))); + weak_factory_.GetWeakPtr(), std::move(receiver))); } void ArcOemCryptoBridge::ConnectToDaemon( - mojom::OemCryptoServiceRequest request) { + mojo::PendingReceiver<mojom::OemCryptoService> receiver) { if (!oemcrypto_host_daemon_remote_) { VLOG(1) << "Mojo connection is already lost."; return; @@ -155,18 +156,18 @@ content::GetIOThreadTaskRunner({}).get(), FROM_HERE, base::BindOnce(&GetGpuBufferManagerOnIOThread), base::BindOnce(&ArcOemCryptoBridge::FinishConnectingToDaemon, - weak_factory_.GetWeakPtr(), std::move(request))); + weak_factory_.GetWeakPtr(), std::move(receiver))); } void ArcOemCryptoBridge::FinishConnectingToDaemon( - mojom::OemCryptoServiceRequest request, + mojo::PendingReceiver<mojom::OemCryptoService> receiver, mojo::PendingRemote<mojom::ProtectedBufferManager> gpu_buffer_manager) { if (!oemcrypto_host_daemon_remote_) { VLOG(1) << "Mojo connection is already lost."; return; } - oemcrypto_host_daemon_remote_->Connect(std::move(request), + oemcrypto_host_daemon_remote_->Connect(std::move(receiver), std::move(gpu_buffer_manager)); }
diff --git a/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h index d280fc2..6d9359c3 100644 --- a/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h +++ b/chrome/browser/chromeos/arc/oemcrypto/arc_oemcrypto_bridge.h
@@ -13,6 +13,7 @@ #include "components/arc/mojom/oemcrypto.mojom.h" #include "components/arc/mojom/oemcrypto_daemon.mojom.h" #include "components/keyed_service/core/keyed_service.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" @@ -37,14 +38,16 @@ ~ArcOemCryptoBridge() override; // OemCrypto Mojo host interface - void Connect(mojom::OemCryptoServiceRequest request) override; + void Connect( + mojo::PendingReceiver<mojom::OemCryptoService> receiver) override; private: - void OnBootstrapMojoConnection(mojom::OemCryptoServiceRequest request, - bool result); - void ConnectToDaemon(mojom::OemCryptoServiceRequest request); + void OnBootstrapMojoConnection( + mojo::PendingReceiver<mojom::OemCryptoService> receiver, + bool result); + void ConnectToDaemon(mojo::PendingReceiver<mojom::OemCryptoService> receiver); void FinishConnectingToDaemon( - mojom::OemCryptoServiceRequest request, + mojo::PendingReceiver<mojom::OemCryptoService> receiver, mojo::PendingRemote<mojom::ProtectedBufferManager> gpu_buffer_manager); void OnMojoConnectionError();
diff --git a/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.cc b/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.cc index a3bee310..7d87525 100644 --- a/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.cc +++ b/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.cc
@@ -76,7 +76,7 @@ int32_t task_id, int32_t surface_id, int32_t top_margin, - mojom::PrintSessionInstancePtr instance, + mojo::PendingRemote<mojom::PrintSessionInstance> instance, StartPrintInCustomTabCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); base::ThreadPool::PostTaskAndReplyWithResult( @@ -91,7 +91,7 @@ int32_t task_id, int32_t surface_id, int32_t top_margin, - mojom::PrintSessionInstancePtr instance, + mojo::PendingRemote<mojom::PrintSessionInstance> instance, StartPrintInCustomTabCallback callback, base::FilePath file_path) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
diff --git a/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.h b/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.h index b9c8d34..1060bc2 100644 --- a/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.h +++ b/chrome/browser/chromeos/arc/print_spooler/arc_print_spooler_bridge.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "components/arc/mojom/print_spooler.mojom.h" #include "components/keyed_service/core/keyed_service.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/system/platform_handle.h" class Profile; @@ -37,19 +38,21 @@ ~ArcPrintSpoolerBridge() override; // mojom::PrintSpoolerHost: - void StartPrintInCustomTab(mojo::ScopedHandle scoped_handle, - int32_t task_id, - int32_t surface_id, - int32_t top_margin, - mojom::PrintSessionInstancePtr instance, - StartPrintInCustomTabCallback callback) override; + void StartPrintInCustomTab( + mojo::ScopedHandle scoped_handle, + int32_t task_id, + int32_t surface_id, + int32_t top_margin, + mojo::PendingRemote<mojom::PrintSessionInstance> instance, + StartPrintInCustomTabCallback callback) override; - void OnPrintDocumentSaved(int32_t task_id, - int32_t surface_id, - int32_t top_margin, - mojom::PrintSessionInstancePtr instance, - StartPrintInCustomTabCallback callback, - base::FilePath file_path); + void OnPrintDocumentSaved( + int32_t task_id, + int32_t surface_id, + int32_t top_margin, + mojo::PendingRemote<mojom::PrintSessionInstance> instance, + StartPrintInCustomTabCallback callback, + base::FilePath file_path); private: ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
diff --git a/chrome/browser/chromeos/arc/print_spooler/print_session_impl.cc b/chrome/browser/chromeos/arc/print_spooler/print_session_impl.cc index c8d915b..6173458 100644 --- a/chrome/browser/chromeos/arc/print_spooler/print_session_impl.cc +++ b/chrome/browser/chromeos/arc/print_spooler/print_session_impl.cc
@@ -211,7 +211,7 @@ mojo::PendingRemote<mojom::PrintSessionHost> PrintSessionImpl::Create( std::unique_ptr<content::WebContents> web_contents, std::unique_ptr<ash::ArcCustomTab> custom_tab, - mojom::PrintSessionInstancePtr instance) { + mojo::PendingRemote<mojom::PrintSessionInstance> instance) { DCHECK(custom_tab); if (!instance) return mojo::NullRemote(); @@ -227,7 +227,7 @@ PrintSessionImpl::PrintSessionImpl( std::unique_ptr<content::WebContents> web_contents, std::unique_ptr<ash::ArcCustomTab> custom_tab, - mojom::PrintSessionInstancePtr instance, + mojo::PendingRemote<mojom::PrintSessionInstance> instance, mojo::PendingReceiver<mojom::PrintSessionHost> receiver) : ArcCustomTabModalDialogHost(std::move(custom_tab), web_contents.get()), instance_(std::move(instance)),
diff --git a/chrome/browser/chromeos/arc/print_spooler/print_session_impl.h b/chrome/browser/chromeos/arc/print_spooler/print_session_impl.h index 04ba140a..2c41faa 100644 --- a/chrome/browser/chromeos/arc/print_spooler/print_session_impl.h +++ b/chrome/browser/chromeos/arc/print_spooler/print_session_impl.h
@@ -20,6 +20,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/platform_handle.h" namespace ash { @@ -42,7 +43,7 @@ static mojo::PendingRemote<mojom::PrintSessionHost> Create( std::unique_ptr<content::WebContents> web_contents, std::unique_ptr<ash::ArcCustomTab> custom_tab, - mojom::PrintSessionInstancePtr instance); + mojo::PendingRemote<mojom::PrintSessionInstance> instance); PrintSessionImpl(const PrintSessionImpl&) = delete; PrintSessionImpl& operator=(const PrintSessionImpl&) = delete; @@ -54,7 +55,7 @@ private: PrintSessionImpl(std::unique_ptr<content::WebContents> web_contents, std::unique_ptr<ash::ArcCustomTab> custom_tab, - mojom::PrintSessionInstancePtr instance, + mojo::PendingRemote<mojom::PrintSessionInstance> instance, mojo::PendingReceiver<mojom::PrintSessionHost> receiver); friend class content::WebContentsUserData<PrintSessionImpl>; @@ -95,7 +96,7 @@ void StartPrintNow(); // Used to send messages to ARC and request a new print document. - mojom::PrintSessionInstancePtr instance_; + mojo::Remote<mojom::PrintSessionInstance> instance_; // Receiver for PrintRenderer. mojo::AssociatedReceiver<printing::mojom::PrintRenderer>
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index 279a954..e8df356 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -84,7 +84,7 @@ #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/wizard_controller.h" -#include "chrome/browser/chromeos/net/network_health.h" +#include "chrome/browser/chromeos/net/network_health/network_health_service.h" #include "chrome/browser/chromeos/net/network_portal_detector_impl.h" #include "chrome/browser/chromeos/net/network_pref_state_observer.h" #include "chrome/browser/chromeos/net/network_throttling_observer.h" @@ -879,7 +879,9 @@ network_pref_state_observer_ = std::make_unique<NetworkPrefStateObserver>(); // Initialize the NetworkHealth aggregator. - network_health_ = std::make_unique<network_health::NetworkHealth>(); + network_health::NetworkHealthService* network_health_service = + network_health::NetworkHealthService::GetInstance(); + DCHECK(network_health_service); // Initialize input methods. input_method::InputMethodManager* manager = @@ -1054,7 +1056,6 @@ // We should remove observers attached to D-Bus clients before // DBusThreadManager is shut down. network_pref_state_observer_.reset(); - network_health_.reset(); power_metrics_reporter_.reset(); renderer_freezer_.reset(); fast_transition_observer_.reset();
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index 6978e82..64c7e869 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -70,10 +70,6 @@ class DBusServices; } // namespace internal -namespace network_health { -class NetworkHealth; -} // namespace network_health - namespace power { class SmartChargingManager; namespace ml { @@ -117,7 +113,6 @@ private: std::unique_ptr<default_app_order::ExternalLoader> app_order_loader_; - std::unique_ptr<network_health::NetworkHealth> network_health_; std::unique_ptr<NetworkPrefStateObserver> network_pref_state_observer_; std::unique_ptr<IdleActionWarningObserver> idle_action_warning_observer_; std::unique_ptr<RendererFreezer> renderer_freezer_;
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_session.cc b/chrome/browser/chromeos/login/demo_mode/demo_session.cc index 6f23cf5..3df9a936f 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_session.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_session.cc
@@ -450,11 +450,13 @@ Profile* const profile = ProfileManager::GetActiveUserProfile(); DCHECK(profile); - const base::FilePath downloads = - file_manager::util::GetDownloadsFolderForProfile(profile); + // TODO(b/158057730): Revert this back to Downloads once the ARC++ Download + // folder bug in Managed Guest Sessions has been fixed. + const base::FilePath my_files = + file_manager::util::GetMyFilesFolderForProfile(profile); base::ThreadPool::PostTask( FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, - base::BindOnce(&InstallDemoMedia, demo_resources_->path(), downloads)); + base::BindOnce(&InstallDemoMedia, demo_resources_->path(), my_files)); } void DemoSession::LoadAndLaunchHighlightsApp() {
diff --git a/chrome/browser/chromeos/login/signin/signin_error_notifier_factory_ash.cc b/chrome/browser/chromeos/login/signin/signin_error_notifier_factory_ash.cc index 83fc33c853..4738bef8 100644 --- a/chrome/browser/chromeos/login/signin/signin_error_notifier_factory_ash.cc +++ b/chrome/browser/chromeos/login/signin/signin_error_notifier_factory_ash.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/notifications/notification_display_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/signin_error_controller_factory.h" +#include "chromeos/constants/chromeos_switches.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" SigninErrorNotifierFactory::SigninErrorNotifierFactory() @@ -35,6 +36,10 @@ KeyedService* SigninErrorNotifierFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { + // If this is during dummy login from tests, suppress the notification. + if (chromeos::switches::IsGaiaServicesDisabled()) + return nullptr; + Profile* profile = static_cast<Profile*>(context); return new SigninErrorNotifier( SigninErrorControllerFactory::GetForProfile(profile), profile);
diff --git a/chrome/browser/chromeos/net/network_health.cc b/chrome/browser/chromeos/net/network_health/network_health.cc similarity index 90% rename from chrome/browser/chromeos/net/network_health.cc rename to chrome/browser/chromeos/net/network_health/network_health.cc index 53409be..64c6f91 100644 --- a/chrome/browser/chromeos/net/network_health.cc +++ b/chrome/browser/chromeos/net/network_health/network_health.cc
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/chromeos/net/network_health.h" +#include "chrome/browser/chromeos/net/network_health/network_health.h" +#include <map> #include <vector> -#include "chrome/browser/chromeos/net/mojom/network_health.mojom.h" +#include "chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom.h" #include "chromeos/network/network_event_log.h" #include "chromeos/services/network_config/in_process_instance.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" @@ -84,18 +85,18 @@ RefreshNetworkHealthState(); } -NetworkHealth::~NetworkHealth() {} +NetworkHealth::~NetworkHealth() = default; void NetworkHealth::CreateNetworkHealthState() { // If the device information has not been collected, the NetworkHealthState // cannot be created. - if (device_properties_.size() == 0) + if (device_properties_.empty()) return; network_health_state_.networks.clear(); - std::unordered_map<network_config::mojom::NetworkType, - network_config::mojom::DeviceStatePropertiesPtr> + std::map<network_config::mojom::NetworkType, + network_config::mojom::DeviceStatePropertiesPtr> device_type_map; // This function only supports one Network structure per underlying device. If @@ -123,8 +124,8 @@ // Devices that have an kUnavailable state are not valid. if (device_prop.second->device_state == network_config::mojom::DeviceStateType::kUnavailable) { - NET_LOG(ERROR) << "Device in unexpected state: " - << device_prop.second->device_state; + NET_LOG(ERROR) << "Device in unexpected unavailable state: " + << device_prop.second->type; continue; } @@ -133,9 +134,9 @@ } } -void NetworkHealth::RefreshNetworkHealthState() { - RequestNetworkStateList(); - RequestDeviceStateList(); +void NetworkHealth::BindRemote( + mojo::PendingReceiver<mojom::NetworkHealthService> receiver) { + receivers_.Add(this, std::move(receiver)); } const mojom::NetworkHealthStatePtr NetworkHealth::GetNetworkHealthState() { @@ -143,6 +144,11 @@ return network_health_state_.Clone(); } +void NetworkHealth::RefreshNetworkHealthState() { + RequestNetworkStateList(); + RequestDeviceStateList(); +} + void NetworkHealth::GetNetworkList(GetNetworkListCallback callback) { std::move(callback).Run(mojo::Clone(network_health_state_.networks)); }
diff --git a/chrome/browser/chromeos/net/network_health.h b/chrome/browser/chromeos/net/network_health/network_health.h similarity index 77% rename from chrome/browser/chromeos/net/network_health.h rename to chrome/browser/chromeos/net/network_health/network_health.h index c790c13..a9a3584 100644 --- a/chrome/browser/chromeos/net/network_health.h +++ b/chrome/browser/chromeos/net/network_health/network_health.h
@@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_H_ -#define CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_H_ +#ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_NETWORK_HEALTH_H_ +#define CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_NETWORK_HEALTH_H_ #include <string> #include <vector> -#include "chrome/browser/chromeos/net/mojom/network_health.mojom.h" +#include "chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" namespace chromeos { @@ -22,6 +24,9 @@ ~NetworkHealth() override; + // Function to bind a NetworkHealthService |receiver|. + void BindRemote(mojo::PendingReceiver<mojom::NetworkHealthService> receiver); + // Returns the current NetworkHealthState. const mojom::NetworkHealthStatePtr GetNetworkHealthState(); @@ -62,6 +67,10 @@ remote_cros_network_config_; mojo::Receiver<network_config::mojom::CrosNetworkConfigObserver> cros_network_config_observer_receiver_{this}; + mojo::Receiver<network_health::mojom::NetworkHealthService> + network_health_receiver_{this}; + + mojo::ReceiverSet<mojom::NetworkHealthService> receivers_; mojom::NetworkHealthState network_health_state_; @@ -74,4 +83,4 @@ } // namespace network_health } // namespace chromeos -#endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_H_ +#endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_NETWORK_HEALTH_H_
diff --git a/chrome/browser/chromeos/net/network_health/network_health_service.cc b/chrome/browser/chromeos/net/network_health/network_health_service.cc new file mode 100644 index 0000000..fb8dc1e --- /dev/null +++ b/chrome/browser/chromeos/net/network_health/network_health_service.cc
@@ -0,0 +1,28 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/net/network_health/network_health_service.h" + +#include "base/no_destructor.h" + +#include "chrome/browser/chromeos/net/network_health/network_health.h" +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" + +namespace chromeos { +namespace network_health { + +NetworkHealthService::NetworkHealthService() = default; + +void NetworkHealthService::BindRemote( + mojo::PendingReceiver<mojom::NetworkHealthService> receiver) { + network_health_.BindRemote(std::move(receiver)); +} + +NetworkHealthService* NetworkHealthService::GetInstance() { + static base::NoDestructor<NetworkHealthService> instance; + return instance.get(); +} + +} // namespace network_health +} // namespace chromeos
diff --git a/chrome/browser/chromeos/net/network_health/network_health_service.h b/chrome/browser/chromeos/net/network_health/network_health_service.h new file mode 100644 index 0000000..5b08bfd --- /dev/null +++ b/chrome/browser/chromeos/net/network_health/network_health_service.h
@@ -0,0 +1,30 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_NETWORK_HEALTH_SERVICE_H_ +#define CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_NETWORK_HEALTH_SERVICE_H_ + +#include "chrome/browser/chromeos/net/network_health/network_health.h" +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" + +namespace chromeos { +namespace network_health { + +class NetworkHealthService { + public: + static NetworkHealthService* GetInstance(); + + NetworkHealthService(); + ~NetworkHealthService() = delete; + + void BindRemote(mojo::PendingReceiver<mojom::NetworkHealthService> receiver); + + private: + NetworkHealth network_health_; +}; + +} // namespace network_health +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_HEALTH_NETWORK_HEALTH_SERVICE_H_
diff --git a/chrome/browser/chromeos/net/network_health_unittest.cc b/chrome/browser/chromeos/net/network_health/network_health_unittest.cc similarity index 98% rename from chrome/browser/chromeos/net/network_health_unittest.cc rename to chrome/browser/chromeos/net/network_health/network_health_unittest.cc index d01e95d..1af5006c 100644 --- a/chrome/browser/chromeos/net/network_health_unittest.cc +++ b/chrome/browser/chromeos/net/network_health/network_health_unittest.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 "chrome/browser/chromeos/net/network_health.h" +#include "chrome/browser/chromeos/net/network_health/network_health.h" #include "base/strings/string_number_conversions.h" -#include "chrome/browser/chromeos/net/mojom/network_health.mojom.h" +#include "chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom.h" #include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/chromeos/net/mojom/BUILD.gn b/chrome/browser/chromeos/net/network_health/public/mojom/BUILD.gn similarity index 68% rename from chrome/browser/chromeos/net/mojom/BUILD.gn rename to chrome/browser/chromeos/net/network_health/public/mojom/BUILD.gn index 713ef8a..6a1fdf4 100644 --- a/chrome/browser/chromeos/net/mojom/BUILD.gn +++ b/chrome/browser/chromeos/net/network_health/public/mojom/BUILD.gn
@@ -7,6 +7,8 @@ mojom("mojom") { sources = [ "network_health.mojom" ] - public_deps = - [ "//chromeos/services/network_config/public/mojom:network_types" ] + public_deps = [ + "//chromeos/services/network_config/public/mojom:network_types", + "//mojo/public/mojom/base", + ] }
diff --git a/chrome/browser/chromeos/net/mojom/OWNERS b/chrome/browser/chromeos/net/network_health/public/mojom/OWNERS similarity index 100% rename from chrome/browser/chromeos/net/mojom/OWNERS rename to chrome/browser/chromeos/net/network_health/public/mojom/OWNERS
diff --git a/chrome/browser/chromeos/net/mojom/network_health.mojom b/chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom similarity index 100% rename from chrome/browser/chromeos/net/mojom/network_health.mojom rename to chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom
diff --git a/chrome/browser/chromeos/scheduler_configuration_manager.cc b/chrome/browser/chromeos/scheduler_configuration_manager.cc index fdc1c1ef..ac1cdc6 100644 --- a/chrome/browser/chromeos/scheduler_configuration_manager.cc +++ b/chrome/browser/chromeos/scheduler_configuration_manager.cc
@@ -91,8 +91,10 @@ // Next, if Finch isn't set, see if the command line passed in a default. config_name = cmdline_default; } else { - // If nothing is found, default to conservative. - config_name = debugd::scheduler_configuration::kConservativeScheduler; + // If nothing is found, default to core isolation scheduling. Note that + // only some kernels support core isolation. debugd checks for support and + // reverts to conservative if core isolation is unavailable. + config_name = debugd::scheduler_configuration::kCoreIsolationScheduler; } // NB: Also send an update when the config gets reset to let the system pick
diff --git a/chrome/browser/chromeos/scheduler_configuration_manager_unittest.cc b/chrome/browser/chromeos/scheduler_configuration_manager_unittest.cc index 0e8a4da5..08e4774 100644 --- a/chrome/browser/chromeos/scheduler_configuration_manager_unittest.cc +++ b/chrome/browser/chromeos/scheduler_configuration_manager_unittest.cc
@@ -117,7 +117,7 @@ manager.AddObserver(this); task_environment_.RunUntilIdle(); - EXPECT_EQ(debugd::scheduler_configuration::kConservativeScheduler, + EXPECT_EQ(debugd::scheduler_configuration::kCoreIsolationScheduler, debug_daemon_client_.scheduler_configuration_name()); EXPECT_EQ(1u, configuration_set_count_); @@ -144,7 +144,7 @@ // Dropping the policy as well reverts to the default configuration. local_state_.RemoveManagedPref(prefs::kSchedulerConfiguration); task_environment_.RunUntilIdle(); - EXPECT_EQ(debugd::scheduler_configuration::kConservativeScheduler, + EXPECT_EQ(debugd::scheduler_configuration::kCoreIsolationScheduler, debug_daemon_client_.scheduler_configuration_name()); EXPECT_EQ(5u, configuration_set_count_); }
diff --git a/chrome/browser/component_updater/recovery_component_installer.cc b/chrome/browser/component_updater/recovery_component_installer.cc index a823d58e..93262310 100644 --- a/chrome/browser/component_updater/recovery_component_installer.cc +++ b/chrome/browser/component_updater/recovery_component_installer.cc
@@ -416,7 +416,8 @@ auto result = update_client::InstallFunctionWrapper( base::BindOnce(&RecoveryComponentInstaller::DoInstall, base::Unretained(this), std::cref(unpack_path))); - base::PostTask(FROM_HERE, base::BindOnce(std::move(callback), result)); + content::GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), result)); } bool RecoveryComponentInstaller::DoInstall(
diff --git a/chrome/browser/downgrade/snapshot_manager.cc b/chrome/browser/downgrade/snapshot_manager.cc index 23132e4..50971b3 100644 --- a/chrome/browser/downgrade/snapshot_manager.cc +++ b/chrome/browser/downgrade/snapshot_manager.cc
@@ -375,7 +375,7 @@ void SnapshotManager::DeleteSnapshotDataForProfile( base::Time delete_begin, const base::FilePath& profile_base_name, - int remove_mask) { + uint64_t remove_mask) { using DataType = ChromeBrowsingDataRemoverDelegate; bool delete_all =
diff --git a/chrome/browser/downgrade/snapshot_manager.h b/chrome/browser/downgrade/snapshot_manager.h index f0102576..7c3e42f 100644 --- a/chrome/browser/downgrade/snapshot_manager.h +++ b/chrome/browser/downgrade/snapshot_manager.h
@@ -53,7 +53,7 @@ // indicates the types of data to be cleared from the profile's snapshots. void DeleteSnapshotDataForProfile(base::Time delete_begin, const base::FilePath& profile_base_name, - int remove_mask); + uint64_t remove_mask); private: virtual std::vector<SnapshotItemDetails> GetUserSnapshotItemDetails() const;
diff --git a/chrome/browser/downgrade/user_data_downgrade.cc b/chrome/browser/downgrade/user_data_downgrade.cc index 3b26674c..6d4599d 100644 --- a/chrome/browser/downgrade/user_data_downgrade.cc +++ b/chrome/browser/downgrade/user_data_downgrade.cc
@@ -123,7 +123,7 @@ void RemoveDataForProfile(base::Time delete_begin, const base::FilePath& profile_path, - int remove_mask) { + uint64_t remove_mask) { SnapshotManager snapshot_manager(profile_path.DirName()); snapshot_manager.DeleteSnapshotDataForProfile( delete_begin, profile_path.BaseName(), remove_mask);
diff --git a/chrome/browser/downgrade/user_data_downgrade.h b/chrome/browser/downgrade/user_data_downgrade.h index 713dbe0f..d6d9b15 100644 --- a/chrome/browser/downgrade/user_data_downgrade.h +++ b/chrome/browser/downgrade/user_data_downgrade.h
@@ -60,7 +60,7 @@ // indicates the types of data to be cleared from the profile's snapshots. void RemoveDataForProfile(base::Time delete_begin, const base::FilePath& profile_path, - int remove_mask); + uint64_t remove_mask); } // namespace downgrade
diff --git a/chrome/browser/downgrade/user_data_downgrade_unittest.cc b/chrome/browser/downgrade/user_data_downgrade_unittest.cc index de0225e..e4d566d 100644 --- a/chrome/browser/downgrade/user_data_downgrade_unittest.cc +++ b/chrome/browser/downgrade/user_data_downgrade_unittest.cc
@@ -159,7 +159,7 @@ EXPECT_TRUE( base::PathExists(snapshot_profile_path_default.Append(item.path))); EXPECT_EQ((item.data_types & - ChromeBrowsingDataRemoverDelegate::DATA_TYPE_BOOKMARKS) == 0, + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_BOOKMARKS) == 0ULL, base::PathExists(snapshot_profile_path_1.Append(item.path))); } @@ -175,7 +175,7 @@ RemoveDataForProfile(base::Time::Min(), profile_path_default, remove_mask); for (const auto& item : profile_items) { EXPECT_EQ( - (item.data_types & remove_mask) == 0, + (item.data_types & remove_mask) == 0ULL, base::PathExists(snapshot_profile_path_default.Append(item.path))); } // Wipe profile 1
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc index 4e8502d..a7690411 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc
@@ -101,7 +101,7 @@ "kFilterableDataTypes must be a subset of " "ChromeBrowsingDataRemoverDelegate::FILTERABLE_DATA_TYPES"); -int MaskForKey(const char* key) { +uint64_t MaskForKey(const char* key) { if (strcmp(key, extension_browsing_data_api_constants::kAppCacheKey) == 0) return content::BrowsingDataRemover::DATA_TYPE_APP_CACHE; if (strcmp(key, extension_browsing_data_api_constants::kCacheKey) == 0) @@ -132,12 +132,12 @@ if (strcmp(key, extension_browsing_data_api_constants::kWebSQLKey) == 0) return content::BrowsingDataRemover::DATA_TYPE_WEB_SQL; - return 0; + return 0ULL; } // Returns false if any of the selected data types are not allowed to be // deleted. -bool IsRemovalPermitted(int removal_mask, PrefService* prefs) { +bool IsRemovalPermitted(uint64_t removal_mask, PrefService* prefs) { // Enterprise policy or user preference might prohibit deleting browser or // download history. if ((removal_mask & ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY) || @@ -455,7 +455,7 @@ bool BrowsingDataRemoverFunction::ParseOriginTypeMask( const base::DictionaryValue& options, - int* origin_type_mask) { + uint64_t* origin_type_mask) { // Parse the |options| dictionary to generate the origin set mask. Default to // UNPROTECTED_WEB if the developer doesn't specify anything. *origin_type_mask = content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; @@ -532,7 +532,7 @@ // Parses the |dataToRemove| argument to generate the removal mask. // Returns false if parse was not successful, i.e. if 'dataToRemove' is not // present or any data-type keys don't have supported (boolean) values. -bool BrowsingDataRemoveFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveFunction::GetRemovalMask(uint64_t* removal_mask) { base::DictionaryValue* data_to_remove; if (!args_->GetDictionary(1, &data_to_remove)) return false; @@ -555,73 +555,82 @@ return false; } -bool BrowsingDataRemoveAppcacheFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveAppcacheFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_APP_CACHE; return true; } -bool BrowsingDataRemoveCacheFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveCacheFunction::GetRemovalMask(uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_CACHE; return true; } -bool BrowsingDataRemoveCookiesFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveCookiesFunction::GetRemovalMask(uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_COOKIES; return true; } -bool BrowsingDataRemoveDownloadsFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveDownloadsFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS; return true; } -bool BrowsingDataRemoveFileSystemsFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveFileSystemsFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_FILE_SYSTEMS; return true; } -bool BrowsingDataRemoveFormDataFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveFormDataFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_FORM_DATA; return true; } -bool BrowsingDataRemoveHistoryFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveHistoryFunction::GetRemovalMask(uint64_t* removal_mask) { *removal_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY; return true; } -bool BrowsingDataRemoveIndexedDBFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveIndexedDBFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_INDEXED_DB; return true; } -bool BrowsingDataRemoveLocalStorageFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveLocalStorageFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE; return true; } -bool BrowsingDataRemovePluginDataFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemovePluginDataFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA; return true; } -bool BrowsingDataRemovePasswordsFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemovePasswordsFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS; return true; } bool BrowsingDataRemoveServiceWorkersFunction::GetRemovalMask( - int* removal_mask) { + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS; return true; } -bool BrowsingDataRemoveCacheStorageFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveCacheStorageFunction::GetRemovalMask( + uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE; return true; } -bool BrowsingDataRemoveWebSQLFunction::GetRemovalMask(int* removal_mask) { +bool BrowsingDataRemoveWebSQLFunction::GetRemovalMask(uint64_t* removal_mask) { *removal_mask = content::BrowsingDataRemover::DATA_TYPE_WEB_SQL; return true; }
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h index 6d39a5df..e181262 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_api.h +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_api.h
@@ -116,7 +116,7 @@ // based on the API call they represent. // Returns whether or not removal mask retrieval was successful. // |removal_mask| is populated with the result, if successful. - virtual bool GetRemovalMask(int* removal_mask) = 0; + virtual bool GetRemovalMask(uint64_t* removal_mask) = 0; // Returns true if the data removal is allowed to pause Sync. Returns true by // default. Subclasses can override it to return false and prevent Sync from @@ -135,7 +135,7 @@ // that can be used with the BrowsingDataRemover. // Returns true if parsing was successful. bool ParseOriginTypeMask(const base::DictionaryValue& options, - int* origin_type_mask); + uint64_t* origin_type_mask); // Parses the developer-provided list of origins into |result|. // Returns whether or not parsing was successful. In case of parse failure, @@ -152,8 +152,8 @@ void OnTaskFinished(); base::Time remove_since_; - int removal_mask_ = 0; - int origin_type_mask_ = 0; + uint64_t removal_mask_ = 0; + uint64_t origin_type_mask_ = 0; std::vector<url::Origin> origins_; content::BrowsingDataFilterBuilder::Mode mode_ = content::BrowsingDataFilterBuilder::Mode::BLACKLIST; @@ -174,7 +174,7 @@ ~BrowsingDataRemoveAppcacheFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveFunction : public BrowsingDataRemoverFunction { @@ -185,7 +185,7 @@ ~BrowsingDataRemoveFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; bool IsPauseSyncAllowed() override; }; @@ -198,7 +198,7 @@ ~BrowsingDataRemoveCacheFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveCookiesFunction : public BrowsingDataRemoverFunction { @@ -210,7 +210,7 @@ ~BrowsingDataRemoveCookiesFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveDownloadsFunction : public BrowsingDataRemoverFunction { @@ -222,7 +222,7 @@ ~BrowsingDataRemoveDownloadsFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveFileSystemsFunction @@ -235,7 +235,7 @@ ~BrowsingDataRemoveFileSystemsFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveFormDataFunction : public BrowsingDataRemoverFunction { @@ -247,7 +247,7 @@ ~BrowsingDataRemoveFormDataFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveHistoryFunction : public BrowsingDataRemoverFunction { @@ -259,7 +259,7 @@ ~BrowsingDataRemoveHistoryFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveIndexedDBFunction : public BrowsingDataRemoverFunction { @@ -271,7 +271,7 @@ ~BrowsingDataRemoveIndexedDBFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveLocalStorageFunction @@ -284,7 +284,7 @@ ~BrowsingDataRemoveLocalStorageFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemovePluginDataFunction @@ -297,7 +297,7 @@ ~BrowsingDataRemovePluginDataFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemovePasswordsFunction : public BrowsingDataRemoverFunction { @@ -309,7 +309,7 @@ ~BrowsingDataRemovePasswordsFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveServiceWorkersFunction @@ -322,7 +322,7 @@ ~BrowsingDataRemoveServiceWorkersFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveCacheStorageFunction @@ -335,7 +335,7 @@ ~BrowsingDataRemoveCacheStorageFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; class BrowsingDataRemoveWebSQLFunction : public BrowsingDataRemoverFunction { @@ -347,7 +347,7 @@ ~BrowsingDataRemoveWebSQLFunction() override {} // BrowsingDataRemoverFunction: - bool GetRemovalMask(int* removal_mask) override; + bool GetRemovalMask(uint64_t* removal_mask) override; }; #endif // CHROME_BROWSER_EXTENSIONS_API_BROWSING_DATA_BROWSING_DATA_API_H_
diff --git a/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc b/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc index eb659ca..953451e7 100644 --- a/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc +++ b/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc
@@ -72,15 +72,17 @@ return remover_->GetLastUsedBeginTimeForTesting(); } - int GetRemovalMask() { return remover_->GetLastUsedRemovalMaskForTesting(); } + uint64_t GetRemovalMask() { + return remover_->GetLastUsedRemovalMaskForTesting(); + } - int GetOriginTypeMask() { + uint64_t GetOriginTypeMask() { return remover_->GetLastUsedOriginTypeMaskForTesting(); } - int GetAsMask(const base::DictionaryValue* dict, - std::string path, - int mask_value) { + uint64_t GetAsMask(const base::DictionaryValue* dict, + std::string path, + uint64_t mask_value) { bool result; EXPECT_TRUE(dict->GetBoolean(path, &result)) << "for " << path; return result ? mask_value : 0; @@ -88,7 +90,7 @@ void RunBrowsingDataRemoveFunctionAndCompareRemovalMask( const std::string& data_types, - int expected_mask) { + uint64_t expected_mask) { auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>(); SCOPED_TRACE(data_types); EXPECT_EQ(NULL, RunFunctionAndReturnSingleResult( @@ -99,15 +101,16 @@ EXPECT_EQ(UNPROTECTED_WEB, GetOriginTypeMask()); } - void RunBrowsingDataRemoveWithKeyAndCompareRemovalMask(const std::string& key, - int expected_mask) { + void RunBrowsingDataRemoveWithKeyAndCompareRemovalMask( + const std::string& key, + uint64_t expected_mask) { RunBrowsingDataRemoveFunctionAndCompareRemovalMask( std::string("{\"") + key + "\": true}", expected_mask); } void RunBrowsingDataRemoveFunctionAndCompareOriginTypeMask( const std::string& protectedStr, - int expected_mask) { + uint64_t expected_mask) { auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>(); SCOPED_TRACE(protectedStr); EXPECT_EQ(NULL, RunFunctionAndReturnSingleResult( @@ -119,7 +122,7 @@ } template <class ShortcutFunction> - void RunAndCompareRemovalMask(int expected_mask) { + void RunAndCompareRemovalMask(uint64_t expected_mask) { scoped_refptr<ShortcutFunction> function = new ShortcutFunction(); SCOPED_TRACE(ShortcutFunction::function_name()); EXPECT_EQ(NULL, @@ -161,8 +164,8 @@ } void SetPrefsAndVerifySettings(int data_type_flags, - int expected_origin_type_mask, - int expected_removal_mask) { + uint64_t expected_origin_type_mask, + uint64_t expected_removal_mask) { PrefService* prefs = browser()->profile()->GetPrefs(); prefs->SetInteger( browsing_data::prefs::kLastClearBrowsingDataTab, @@ -200,8 +203,8 @@ } void SetBasicPrefsAndVerifySettings(int data_type_flags, - int expected_origin_type_mask, - int expected_removal_mask) { + uint64_t expected_origin_type_mask, + uint64_t expected_removal_mask) { PrefService* prefs = browser()->profile()->GetPrefs(); prefs->SetInteger( browsing_data::prefs::kLastClearBrowsingDataTab, @@ -223,8 +226,8 @@ VerifyRemovalMask(expected_origin_type_mask, expected_removal_mask); } - void VerifyRemovalMask(int expected_origin_type_mask, - int expected_removal_mask) { + void VerifyRemovalMask(uint64_t expected_origin_type_mask, + uint64_t expected_removal_mask) { scoped_refptr<BrowsingDataSettingsFunction> function = new BrowsingDataSettingsFunction(); SCOPED_TRACE("settings"); @@ -238,7 +241,7 @@ EXPECT_TRUE(result->GetDictionary("options", &options)); base::DictionaryValue* origin_types; EXPECT_TRUE(options->GetDictionary("originTypes", &origin_types)); - int origin_type_mask = + uint64_t origin_type_mask = GetAsMask(origin_types, "unprotectedWeb", UNPROTECTED_WEB) | GetAsMask(origin_types, "protectedWeb", PROTECTED_WEB) | GetAsMask(origin_types, "extension", EXTENSION); @@ -246,7 +249,7 @@ base::DictionaryValue* data_to_remove; EXPECT_TRUE(result->GetDictionary("dataToRemove", &data_to_remove)); - int removal_mask = + uint64_t removal_mask = GetAsMask(data_to_remove, "appcache", content::BrowsingDataRemover::DATA_TYPE_APP_CACHE) | GetAsMask(data_to_remove, "cache", @@ -467,9 +470,9 @@ prefs->SetBoolean(browsing_data::prefs::kDeleteHostedAppsData, false); prefs->SetBoolean(browsing_data::prefs::kDeletePasswords, false); prefs->SetBoolean(prefs::kClearPluginLSODataEnabled, false); - int expected_mask = content::BrowsingDataRemover::DATA_TYPE_CACHE | - content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS | - ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY; + uint64_t expected_mask = content::BrowsingDataRemover::DATA_TYPE_CACHE | + content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS | + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY; std::string json; // Scoping for the traces. {
diff --git a/chrome/browser/extensions/app_process_apitest.cc b/chrome/browser/extensions/app_process_apitest.cc index 6e0a83c6..5c4c356 100644 --- a/chrome/browser/extensions/app_process_apitest.cc +++ b/chrome/browser/extensions/app_process_apitest.cc
@@ -9,7 +9,6 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" @@ -19,6 +18,7 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/embedder_support/switches.h" #include "components/sync/model/string_ordinal.h" #include "content/public/browser/navigation_entry.h" @@ -619,8 +619,8 @@ true); WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); - PopupBlockerTabHelper* popup_blocker_tab_helper = - PopupBlockerTabHelper::FromWebContents(tab); + blocked_content::PopupBlockerTabHelper* popup_blocker_tab_helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(tab); EXPECT_EQ(1u, popup_blocker_tab_helper->GetBlockedPopupsCount()); }
diff --git a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc index 6cfc3cd..5c987a1e3 100644 --- a/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc +++ b/chrome/browser/lookalikes/lookalike_url_navigation_throttle_browsertest.cc
@@ -183,8 +183,9 @@ features::kLookalikeUrlNavigationSuggestionsUI}); break; case FeatureStatus::kEnabledAndTargetEmbeddingEnabled: - feature_list_.InitAndEnableFeature( - lookalikes::features::kDetectTargetEmbeddingLookalikes); + feature_list_.InitAndEnableFeatureWithParameters( + lookalikes::features::kDetectTargetEmbeddingLookalikes, + {{"enhanced_protection_enabled", "true"}}); break; case FeatureStatus::kEnabled: feature_list_.InitAndDisableFeature( @@ -451,6 +452,12 @@ TargetEmbedding_AnotherTLD_Match) { const GURL kNavigatedUrl = GetURL("google.br-test.com"); const GURL kExpectedSuggestedUrl = GetURLWithoutPath("google.com"); + + // This test only applies when another-TLD is enabled. + if (feature_status() != FeatureStatus::kEnabledAndTargetEmbeddingEnabled) { + return; + } + SetEngagementScore(browser(), kNavigatedUrl, kLowEngagement); TestInterstitialNotShown(browser(), kNavigatedUrl); CheckUkm({kNavigatedUrl}, "MatchType",
diff --git a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc index 457d258..a57dc70 100644 --- a/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc +++ b/chrome/browser/page_load_metrics/observers/ad_metrics/ads_page_load_metrics_observer_browsertest.cc
@@ -562,8 +562,12 @@ } // Test that an ad frame with visible resource gets a FCP. +// +// This test is flaky on multiple platforms https://crbug.com/1090976 +// TODO(https://crbug.com/1090976): Wait until the histogram is recorded instead +// of until 4 resources are complete. IN_PROC_BROWSER_TEST_F(AdsPageLoadMetricsObserverBrowserTest, - FirstContentfulPaintRecorded) { + DISABLED_FirstContentfulPaintRecorded) { SetRulesetWithRules( {subresource_filter::testing::CreateSuffixRule("pixel.png")}); base::HistogramTester histogram_tester;
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 950797b..f74a930 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -289,6 +289,16 @@ kHistogramNavigationTimingNavigationStartToFirstLoaderCallback, expected_count); histogram_tester_.ExpectTotalCount( + internal::kHistogramNavigationTimingNavigationStartToFinalRequestStart, + expected_count); + histogram_tester_.ExpectTotalCount( + internal::kHistogramNavigationTimingNavigationStartToFinalResponseStart, + expected_count); + histogram_tester_.ExpectTotalCount( + internal:: + kHistogramNavigationTimingNavigationStartToFinalLoaderCallback, + expected_count); + histogram_tester_.ExpectTotalCount( internal:: kHistogramNavigationTimingNavigationStartToNavigationCommitSent, expected_count); @@ -302,6 +312,18 @@ internal:: kHistogramNavigationTimingFirstResponseStartToFirstLoaderCallback, expected_count); + histogram_tester_.ExpectTotalCount( + internal:: + kHistogramNavigationTimingFinalRequestStartToFinalResponseStart, + expected_count); + histogram_tester_.ExpectTotalCount( + internal:: + kHistogramNavigationTimingFinalResponseStartToFinalLoaderCallback, + expected_count); + histogram_tester_.ExpectTotalCount( + internal:: + kHistogramNavigationTimingFinalLoaderCallbackToNavigationCommitSent, + expected_count); } content::RenderFrameHost* RenderFrameHost() const {
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc index 021e54d..fa90569f 100644 --- a/chrome/browser/prerender/prerender_browsertest.cc +++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -214,7 +214,7 @@ } // Clears the specified data using BrowsingDataRemover. -void ClearBrowsingData(Browser* browser, int remove_mask) { +void ClearBrowsingData(Browser* browser, uint64_t remove_mask) { content::BrowsingDataRemover* remover = content::BrowserContext::GetBrowsingDataRemover(browser->profile()); content::BrowsingDataRemoverCompletionObserver observer(remover);
diff --git a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc index 130fac6..46d81158 100644 --- a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc +++ b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc
@@ -298,8 +298,13 @@ for (int i = 0; i < kNumberOfPages; ++i) { ASSERT_TRUE(GetPage(i)); // The output is PS encapsulated in EMF. +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 + ASSERT_TRUE(GetPageExpectedEmfData( + GetFileNameForPageNumber("pdf_converter_basic_ps_new_page_", i))); +#else ASSERT_TRUE(GetPageExpectedEmfData( GetFileNameForPageNumber("pdf_converter_basic_ps_page_", i))); +#endif ComparePageEmfHeader(); ComparePageEmfPayload(); } @@ -317,8 +322,13 @@ for (int i = 0; i < kNumberOfPages; ++i) { ASSERT_TRUE(GetPage(i)); // The output is PS encapsulated in EMF. +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 + ASSERT_TRUE(GetPageExpectedEmfData( + GetFileNameForPageNumber("pdf_converter_basic_ps_new_page_", i))); +#else ASSERT_TRUE(GetPageExpectedEmfData( GetFileNameForPageNumber("pdf_converter_basic_ps_page_", i))); +#endif ComparePageEmfHeader(); ComparePageEmfPayload(); } @@ -368,8 +378,13 @@ kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize, /*autorotate=*/false, /*use_color=*/true, PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2); +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 + RunSinglePagePdfToPostScriptConverterTest(pdf_settings, "bug_806746.pdf", + "bug_806746_new.emf"); +#else RunSinglePagePdfToPostScriptConverterTest(pdf_settings, "bug_806746.pdf", "bug_806746.emf"); +#endif } IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, @@ -378,8 +393,13 @@ kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize, /*autorotate=*/false, /*use_color=*/true, PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3); +#ifdef NTDDI_WIN10_VB // Windows 10.0.19041 + RunSinglePagePdfToPostScriptConverterTest(pdf_settings, "bug_806746.pdf", + "bug_806746_new.emf"); +#else RunSinglePagePdfToPostScriptConverterTest(pdf_settings, "bug_806746.pdf", "bug_806746.emf"); +#endif } IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest,
diff --git a/chrome/browser/profile_resetter/profile_resetter.cc b/chrome/browser/profile_resetter/profile_resetter.cc index 0ae51b6..6bd9834c 100644 --- a/chrome/browser/profile_resetter/profile_resetter.cc +++ b/chrome/browser/profile_resetter/profile_resetter.cc
@@ -242,8 +242,9 @@ cookies_remover_ = content::BrowserContext::GetBrowsingDataRemover(profile_); cookies_remover_->AddObserver(this); - int remove_mask = ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA | - content::BrowsingDataRemover::DATA_TYPE_CACHE; + uint64_t remove_mask = + ChromeBrowsingDataRemoverDelegate::DATA_TYPE_SITE_DATA | + content::BrowsingDataRemover::DATA_TYPE_CACHE; PrefService* prefs = profile_->GetPrefs(); DCHECK(prefs);
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index 3952b108..b1cc8208 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -80,6 +80,8 @@ #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/context_menu_data/media_type.h" #include "third_party/blink/public/common/input/web_input_event.h" @@ -892,6 +894,96 @@ ASSERT_EQ(kSuggestedFilename, base::UTF16ToUTF8(suggested_filename).c_str()); } +// Check which commands are present after opening the context menu for the main +// frame. This is a regression test for https://crbug.com/1085040. +IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, + MenuContentsVerification_MainFrame) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url(embedded_test_server()->GetURL("/iframe.html")); + ui_test_utils::NavigateToURL(browser(), url); + + // Open a context menu. + ContextMenuWaiter menu_observer; + blink::WebMouseEvent mouse_event( + blink::WebInputEvent::Type::kMouseDown, + blink::WebInputEvent::kNoModifiers, + blink::WebInputEvent::GetStaticTimeStampForTests()); + mouse_event.button = blink::WebMouseEvent::Button::kRight; + mouse_event.SetPositionInWidget(2, 2); // This is over the main frame. + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event); + mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp); + tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event); + + // Wait for context menu to be visible. + menu_observer.WaitForMenuOpenAndClose(); + + // Verify that the expected context menu items are present. + // + // Note that the assertion below doesn't use exact matching via + // testing::ElementsAre, because some platforms may include unexpected extra + // elements (e.g. an extra separator and IDC=100 has been observed on some Mac + // bots). + EXPECT_THAT(menu_observer.GetCapturedCommandIds(), + testing::IsSupersetOf({IDC_BACK, IDC_FORWARD, IDC_RELOAD, + IDC_SAVE_PAGE, IDC_VIEW_SOURCE, + IDC_CONTENT_CONTEXT_INSPECTELEMENT})); + EXPECT_THAT( + menu_observer.GetCapturedCommandIds(), + testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE))); + EXPECT_THAT(menu_observer.GetCapturedCommandIds(), + testing::Not(testing::Contains(IDC_CONTENT_CONTEXT_RELOADFRAME))); +} + +#if defined(OS_MACOSX) +// TODO(lukasza): https://crbug.com/1090891: Subframe behavior is unexpected on +// some Mac bots. +#define MAYBE_MenuContentsVerification_Subframe \ + DISABLED_MenuContentsVerification_Subframe +#else +#define MAYBE_MenuContentsVerification_Subframe \ + MenuContentsVerification_Subframe +#endif +// Check which commands are present after opening the context menu for a +// subframe. +IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, + MAYBE_MenuContentsVerification_Subframe) { + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url(embedded_test_server()->GetURL("/iframe.html")); + ui_test_utils::NavigateToURL(browser(), url); + + // Open a context menu. + ContextMenuWaiter menu_observer; + blink::WebMouseEvent mouse_event( + blink::WebInputEvent::Type::kMouseDown, + blink::WebInputEvent::kNoModifiers, + blink::WebInputEvent::GetStaticTimeStampForTests()); + mouse_event.button = blink::WebMouseEvent::Button::kRight; + mouse_event.SetPositionInWidget(25, 25); // This is over the subframe. + content::WebContents* tab = + browser()->tab_strip_model()->GetActiveWebContents(); + tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event); + mouse_event.SetType(blink::WebInputEvent::Type::kMouseUp); + tab->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(mouse_event); + + // Wait for context menu to be visible. + menu_observer.WaitForMenuOpenAndClose(); + + // Verify that the expected context menu items are present. + // + // Note that the assertion below doesn't use exact matching via + // testing::ElementsAre, because some platforms may include unexpected extra + // elements (e.g. an extra separator and IDC=100 has been observed on some Mac + // bots). + EXPECT_THAT( + menu_observer.GetCapturedCommandIds(), + testing::IsSupersetOf({IDC_BACK, IDC_FORWARD, IDC_RELOAD, IDC_VIEW_SOURCE, + IDC_SAVE_PAGE, IDC_CONTENT_CONTEXT_VIEWFRAMESOURCE, + IDC_CONTENT_CONTEXT_RELOADFRAME, + IDC_CONTENT_CONTEXT_INSPECTELEMENT})); +} + // Check filename on clicking "Save Link As" is ignored for cross origin. IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, SuggestedFileNameCrossOrigin) { // Register observer.
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc index da2bb1f..5fc1de23 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.cc
@@ -64,8 +64,18 @@ return params_; } +const std::vector<int>& ContextMenuWaiter::GetCapturedCommandIds() const { + return captured_command_ids_; +} + void ContextMenuWaiter::Cancel(RenderViewContextMenu* context_menu) { params_ = context_menu->params(); + + const ui::SimpleMenuModel& menu_model = context_menu->menu_model(); + captured_command_ids_.reserve(menu_model.GetItemCount()); + for (int i = 0; i < menu_model.GetItemCount(); ++i) + captured_command_ids_.push_back(menu_model.GetCommandIdAt(i)); + if (maybe_command_to_execute_) context_menu->ExecuteCommand(*maybe_command_to_execute_, 0); context_menu->Cancel();
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h index 6e131fe..524f68b 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h
@@ -36,6 +36,7 @@ ~ContextMenuWaiter(); content::ContextMenuParams& params(); + const std::vector<int>& GetCapturedCommandIds() const; // Wait until the context menu is opened and closed. void WaitForMenuOpenAndClose(); @@ -46,6 +47,8 @@ void Cancel(RenderViewContextMenu* context_menu); content::ContextMenuParams params_; + std::vector<int> captured_command_ids_; + base::RunLoop run_loop_; base::Optional<int> maybe_command_to_execute_;
diff --git a/chrome/browser/resources/chromeos/BUILD.gn b/chrome/browser/resources/chromeos/BUILD.gn index d4f57c7..e7537c8 100644 --- a/chrome/browser/resources/chromeos/BUILD.gn +++ b/chrome/browser/resources/chromeos/BUILD.gn
@@ -34,6 +34,26 @@ output_dir = "$root_gen_dir/chrome" } +grit("network_health_resources") { + source = "network_ui/network_health_resources.grd" + + defines = chrome_grit_defines + outputs = [ + "grit/network_health_resources.h", + "grit/network_health_resources_map.cc", + "grit/network_health_resources_map.h", + "network_health_resources.pak", + ] + output_dir = "$root_gen_dir/chrome" + + deps = [ "//chrome/browser/chromeos/net/network_health/public/mojom:mojom_js_library_for_compile" ] + + grit_flags = [ + "-E", + "mojom_root=" + rebase_path(root_gen_dir, root_build_dir), + ] +} + grit("camera_resources") { source = "camera/camera_resources.grd"
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/metrics_utils.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/metrics_utils.js index 5912ac6..8ed3b15b 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/metrics_utils.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/metrics_utils.js
@@ -34,6 +34,9 @@ chrome.metricsPrivate.recordEnumerationValue( MetricsUtils.START_SPEECH_METHOD_METRIC.METRIC_NAME, method, MetricsUtils.START_SPEECH_METHOD_METRIC.EVENT_COUNT); + chrome.metricsPrivate.recordBoolean( + MetricsUtils.BACKGROUND_SHADING_METRIC, + prefsManager.backgroundShadingEnabled()); } /** @@ -126,3 +129,10 @@ */ MetricsUtils.WORD_HIGHLIGHTING_METRIC = 'Accessibility.CrosSelectToSpeak.WordHighlighting'; + +/** + * The background shading metric name. + * @type {string} + */ +MetricsUtils.BACKGROUND_SHADING_METRIC = + 'Accessibility.CrosSelectToSpeak.BackgroundShading';
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/options.html b/chrome/browser/resources/chromeos/accessibility/select_to_speak/options.html index 1e1daba..8f1fabf 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/options.html +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/options.html
@@ -73,6 +73,14 @@ </div> </div> </div> + <div class="option" id="backgroundShadingOption"> + <label id="backgroundShadingLabel" class="i18n" + msgid="options_background_shading_description"> + </label> + <input id="backgroundShading" type="checkbox" role="switch" + class="checkbox" name="backgroundShading" + aria-labeledby="backgroundShadingLabel"> + </div> </div> </div>
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js index 64f03c98..268421c2d7 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/prefs_manager.js
@@ -34,9 +34,8 @@ /** @private {boolean} */ this.migrationInProgress_ = false; - /** @private {string} */ - // TODO(crbug.com/1079424): Add this to Select-to-Speak settings UI. - this.focusRingBackgroundColor_ = '#0000'; + /** @private {boolean} */ + this.backgroundShadingEnabled_ = false; } /** @@ -219,7 +218,10 @@ initPreferences() { var updatePrefs = () => { chrome.storage.sync.get( - ['voice', 'rate', 'pitch', 'wordHighlight', 'highlightColor'], + [ + 'voice', 'rate', 'pitch', 'wordHighlight', 'highlightColor', + 'backgroundShading' + ], (prefs) => { if (prefs['voice']) { this.voiceNameFromPrefs_ = prefs['voice']; @@ -234,6 +236,12 @@ } else { chrome.storage.sync.set({'highlightColor': this.highlightColor_}); } + if (prefs['backgroundShading'] !== undefined) { + this.backgroundShadingEnabled_ = prefs['backgroundShading']; + } else { + chrome.storage.sync.set( + {'backgroundShading': this.backgroundShadingEnabled_}); + } if (prefs['rate'] && prefs['pitch']) { // Removes 'rate' and 'pitch' prefs after migrating data to global // TTS settings if appropriate. @@ -319,11 +327,11 @@ /** * Gets the user's focus ring background color. If the user disabled greying * out the background, alpha will be set to fully transparent. - * @return {string} hex code for the background of the focus rings. + * @return {boolean} True if the background shade should be drawn. * @public */ - focusRingBackgroundColor() { - return this.focusRingBackgroundColor_; + backgroundShadingEnabled() { + return this.backgroundShadingEnabled_; } }
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js index 45765896..a31c8f0 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js
@@ -16,6 +16,11 @@ const GSUITE_APP_REGEXP = /^https:\/\/docs\.(?:sandbox\.)?google\.com\/(?:(?:presentation)|(?:document)|(?:spreadsheets)|(?:drawings)){1}\//; +// A RGBA hex string for the default background shading color, which is black at +// 40% opacity (hex 66). This should be equivalent to using +// AshColorProvider::ShieldLayerType kShield40. +const DEFAULT_BACKGROUND_SHADING_COLOR = '#0006'; + /** * Determines if a node is in one of the known Google GSuite apps that needs * special case treatment for speaking selected text. Not all Google GSuite @@ -426,13 +431,15 @@ * @private */ setFocusRings_(rects, drawBackground) { + let color = '#0000'; // Fully transparent. + if (drawBackground && this.prefsManager_.backgroundShadingEnabled()) { + color = DEFAULT_BACKGROUND_SHADING_COLOR; + } chrome.accessibilityPrivate.setFocusRings([{ rects, type: chrome.accessibilityPrivate.FocusType.GLOW, color: this.prefsManager_.focusRingColor(), - backgroundColor: drawBackground ? - this.prefsManager_.focusRingBackgroundColor() : - '#0000' + backgroundColor: color, }]); }
diff --git a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js index b34bf463..5dff300 100644 --- a/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js +++ b/chrome/browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_options.js
@@ -32,6 +32,7 @@ select.disabled = true; } }); + this.syncCheckboxControlToPref_('backgroundShading', 'backgroundShading'); this.setUpHighlightListener_(); this.setUpTtsButtonClickListener_(); chrome.metricsPrivate.recordUserAction(
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings.grdp b/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings.grdp index fa31306e..f383f1e 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings.grdp +++ b/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings.grdp
@@ -45,6 +45,9 @@ <message desc="Example of a word highlight on a light background in the Select-to-speak options dialog." name="IDS_SELECT_TO_SPEAK_OPTIONS_HIGHLIGHT_LIGHT"> Light background </message> +<message desc="Label for option to fade the background outside of the focus ring to improve focus on what is being spoken." name="IDS_SELECT_TO_SPEAK_OPTIONS_BACKGROUND_SHADING_DESCRIPTION"> + Shade content not being read +</message> <message desc="Link to the Text-to-Speech settings page." name="IDS_SELECT_TO_SPEAK_OPTIONS_TEXT_TO_SPEECH_SETTINGS"> Personalize Text-to-Speech settings </message>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings_grdp/IDS_SELECT_TO_SPEAK_OPTIONS_BACKGROUND_SHADING_DESCRIPTION.png.sha1 b/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings_grdp/IDS_SELECT_TO_SPEAK_OPTIONS_BACKGROUND_SHADING_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..13af73e6 --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/strings/select_to_speak_strings_grdp/IDS_SELECT_TO_SPEAK_OPTIONS_BACKGROUND_SHADING_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +e724fa539ceb823ea6de17e75303a16608d93ade \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/network_ui/BUILD.gn b/chrome/browser/resources/chromeos/network_ui/BUILD.gn index 6060563..8d7e61f 100644 --- a/chrome/browser/resources/chromeos/network_ui/BUILD.gn +++ b/chrome/browser/resources/chromeos/network_ui/BUILD.gn
@@ -10,6 +10,7 @@ js_library("network_ui") { deps = [ + "//chrome/browser/chromeos/net/network_health/public/mojom:mojom_js_library_for_compile", "//chromeos/services/network_config/public/mojom:mojom_js_library_for_compile", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider", "//ui/webui/resources/cr_components/chromeos/network:network_icon",
diff --git a/chrome/browser/resources/chromeos/network_ui/network_health_resources.grd b/chrome/browser/resources/chromeos/network_ui/network_health_resources.grd new file mode 100644 index 0000000..79969e61 --- /dev/null +++ b/chrome/browser/resources/chromeos/network_ui/network_health_resources.grd
@@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> + <outputs> + <output filename="grit/network_health_resources.h" type="rc_header"> + <emit emit_type='prepend'></emit> + </output> + <output filename="grit/network_health_resources_map.cc" + type="resource_file_map_source" /> + <output filename="grit/network_health_resources_map.h" + type="resource_map_header" /> + <output filename="network_health_resources.pak" type="data_package" /> + </outputs> + <release seq="1"> + <includes> + <include name="IDR_NETWORK_HEALTH_MOJOM_HTML" + file="${mojom_root}/chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom.html" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> + <include name="IDR_NETWORK_HEALTH_MOJOM_LITE_JS" + file="${mojom_root}/chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom-lite.js" + use_base_dir="false" + type="BINDATA" + compress="gzip" /> + </includes> + </release> +</grit>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.html b/chrome/browser/resources/chromeos/network_ui/network_ui.html index 3da4104b..c39ef48 100644 --- a/chrome/browser/resources/chromeos/network_ui/network_ui.html +++ b/chrome/browser/resources/chromeos/network_ui/network_ui.html
@@ -6,8 +6,10 @@ <title id="network">$i18n{titleText}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> <link rel="stylesheet" href="chrome://network/network_ui.css"> + <link rel="import" href="chrome://network/mojo/network_health/network_health.mojom.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/mojo_interface_provider.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_icon.html"> + <link rel="import" href="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/network/network_select.html"> <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html"> @@ -54,6 +56,10 @@ </cr-button> </div> + + <h2>$i18n{networkHealthLabel}</h2> + <div id="network-health"></div> + <h2>$i18n{networkListsLabel}</h2> <div>$i18n{clickToExpandText}</div>
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.js b/chrome/browser/resources/chromeos/network_ui/network_ui.js index c881e50..9f362c9 100644 --- a/chrome/browser/resources/chromeos/network_ui/network_ui.js +++ b/chrome/browser/resources/chromeos/network_ui/network_ui.js
@@ -45,6 +45,13 @@ */ let networkConfig = null; + + /** + * Network Health mojo remote. + * @type {?chromeos.networkHealth.mojom.NetworkHealthServiceRemote} + */ + let networkHealth = null; + /** * Creates and returns a typed HTMLTableCellElement. * @@ -527,11 +534,23 @@ }); }; + /** + * Requests the NetworkHealthState and updates the page. + */ + const requestNetworkHealth = function() { + networkHealth.getHealthSnapshot().then(result => { + $('network-health').textContent = JSON.stringify(result, null, '\t'); + }); + }; + /** Initialize NetworkUI state. */ const init = function() { networkConfig = network_config.MojoInterfaceProviderImpl.getInstance() .getMojoServiceRemote(); + networkHealth = + chromeos.networkHealth.mojom.NetworkHealthService.getRemote(); + /** Set the refresh rate if the interval is found in the url. */ const interval = new URL(window.location.href).searchParams.get('refresh'); if (interval) { @@ -589,6 +608,7 @@ init(); requestNetworks(); requestGlobalPolicy(); + requestNetworkHealth(); }); document.addEventListener('custom-item-selected', function(event) {
diff --git a/chrome/browser/resources/settings/autofill_page/autofill_page.html b/chrome/browser/resources/settings/autofill_page/autofill_page.html index 2e1c610a..ac04ebcfe 100644 --- a/chrome/browser/resources/settings/autofill_page/autofill_page.html +++ b/chrome/browser/resources/settings/autofill_page/autofill_page.html
@@ -37,6 +37,15 @@ </passwords-section> </settings-subpage> </template> + <!-- TODO(crbug.com/1049141): Add a learn-more-url, which will cause the + (?) button to appear. --> + <template is="dom-if" route-path="/passwords/device" no-search> + <settings-subpage + page-title="$i18n{passwordsDevice}" + search-label="$i18n{searchPasswords}" + search-term="{{passwordFilter_}}"> + </settings-subpage> + </template> <template is="dom-if" route-path="/passwords/check" no-search="[[!enablePasswordCheck_]]"> <settings-subpage
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index 80463b6..9320e5f3 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -138,6 +138,10 @@ r.AUTOFILL = r.BASIC.createSection('/autofill', 'autofill'); r.PASSWORDS = r.AUTOFILL.createChild('/passwords'); + if (loadTimeData.getBoolean('enableAccountStorage')) { + r.DEVICE_PASSWORDS = r.PASSWORDS.createChild('device'); + } + if (loadTimeData.getBoolean('enablePasswordCheck')) { r.CHECK_PASSWORDS = r.PASSWORDS.createChild('check'); }
diff --git a/chrome/browser/resources/settings/settings_routes.js b/chrome/browser/resources/settings/settings_routes.js index 37e4d0b9..85669a7 100644 --- a/chrome/browser/resources/settings/settings_routes.js +++ b/chrome/browser/resources/settings/settings_routes.js
@@ -33,6 +33,7 @@ * MANAGE_PROFILE: !Route, * ON_STARTUP: !Route, * PASSWORDS: !Route, + * DEVICE_PASSWORDS: !Route, * PAYMENTS: !Route, * PEOPLE: !Route, * PRINTING: !Route,
diff --git a/chrome/browser/subresource_filter/subresource_filter_abusive_unittest.cc b/chrome/browser/subresource_filter/subresource_filter_abusive_unittest.cc index d376ade..c57ea35 100644 --- a/chrome/browser/subresource_filter/subresource_filter_abusive_unittest.cc +++ b/chrome/browser/subresource_filter/subresource_filter_abusive_unittest.cc
@@ -9,7 +9,6 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h" #include "chrome/browser/subresource_filter/subresource_filter_test_harness.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" #include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" #include "components/safe_browsing/core/db/util.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.h"
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 58f50f38..ea58cd2 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -63,10 +63,8 @@ "autofill/test/test_autofill_bubble_handler.h", "blocked_content/blocked_window_params.cc", "blocked_content/blocked_window_params.h", - "blocked_content/popup_blocker.cc", - "blocked_content/popup_blocker.h", - "blocked_content/popup_blocker_tab_helper.cc", - "blocked_content/popup_blocker_tab_helper.h", + "blocked_content/chrome_popup_navigation_delegate.cc", + "blocked_content/chrome_popup_navigation_delegate.h", "blocked_content/tab_under_navigation_throttle.cc", "blocked_content/tab_under_navigation_throttle.h", "browser_dialogs.cc", @@ -2122,7 +2120,9 @@ "//ash/shortcut_viewer", "//chrome/browser/chromeos", "//chrome/browser/chromeos:backdrop_wallpaper_proto", + "//chrome/browser/chromeos/net/network_health/public/mojom:mojom", "//chrome/browser/resources/chromeos:camera_resources", + "//chrome/browser/resources/chromeos:network_health_resources", "//chrome/browser/ui/webui/app_management:mojo_bindings", "//chrome/browser/ui/webui/chromeos/add_supervision:mojo_bindings", "//chrome/browser/ui/webui/chromeos/crostini_installer:mojo_bindings",
diff --git a/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc b/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc index 9ac7932e..22231f2 100644 --- a/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc +++ b/chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc
@@ -12,8 +12,8 @@ #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/grit/generated_resources.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" @@ -122,15 +122,17 @@ // Launch popups. content::WebContents* web_contents = InfoBarService::WebContentsFromInfoBar(infobar()); - PopupBlockerTabHelper* popup_blocker_helper = - PopupBlockerTabHelper::FromWebContents(web_contents); + blocked_content::PopupBlockerTabHelper* popup_blocker_helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); DCHECK(popup_blocker_helper); - PopupBlockerTabHelper::PopupIdMap blocked_popups = + blocked_content::PopupBlockerTabHelper::PopupIdMap blocked_popups = popup_blocker_helper->GetBlockedPopupRequests(); - for (PopupBlockerTabHelper::PopupIdMap::iterator it = blocked_popups.begin(); - it != blocked_popups.end(); ++it) + for (blocked_content::PopupBlockerTabHelper::PopupIdMap::iterator it = + blocked_popups.begin(); + it != blocked_popups.end(); ++it) { popup_blocker_helper->ShowBlockedPopup(it->first, WindowOpenDisposition::CURRENT_TAB); + } content_settings::RecordPopupsAction( content_settings::POPUPS_ACTION_CLICKED_ALWAYS_SHOW_ON_MOBILE);
diff --git a/chrome/browser/ui/ash/back_gesture_browsertest.cc b/chrome/browser/ui/ash/back_gesture_browsertest.cc new file mode 100644 index 0000000..fc7a635 --- /dev/null +++ b/chrome/browser/ui/ash/back_gesture_browsertest.cc
@@ -0,0 +1,210 @@ +// Copyright 2020 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 "ash/public/cpp/tablet_mode.h" +#include "ash/public/cpp/test/shell_test_api.h" +#include "base/path_service.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" +#include "content/public/test/hit_test_region_observer.h" +#include "net/dns/mock_host_resolver.h" +#include "ui/aura/window.h" +#include "ui/base/test/ui_controls_aura.h" +#include "ui/events/test/event_generator.h" +#include "ui/events/types/event_type.h" + +namespace { + +// The class to record received gesture events and key events to verify if back +// gesture has been performed. +class BackGestureEventRecorder : public ui::EventHandler { + public: + BackGestureEventRecorder() = default; + BackGestureEventRecorder(const BackGestureEventRecorder&) = delete; + BackGestureEventRecorder& operator=(const BackGestureEventRecorder&) = delete; + ~BackGestureEventRecorder() override = default; + + // ui::EventHandler: + void OnGestureEvent(ui::GestureEvent* event) override { + received_event_types_.insert(event->type()); + if (wait_for_event_ == event->type() && run_loop_) { + run_loop_->Quit(); + wait_for_event_ = ui::EventType::ET_UNKNOWN; + } + } + + void OnKeyEvent(ui::KeyEvent* event) override { + // If back gesture can be performed, a ui::VKEY_BROWSR_BACK key pressed and + // key released will be generated. + received_event_types_.insert(event->type()); + } + + void WaitUntilReceivedGestureEvent(ui::EventType event_type) { + wait_for_event_ = event_type; + run_loop_ = std::make_unique<base::RunLoop>(); + run_loop_->Run(); + } + + bool HasReceivedEvent(ui::EventType event_type) { + return base::Contains(received_event_types_, event_type); + } + + void Reset() { + received_event_types_.clear(); + wait_for_event_ = ui::EventType::ET_UNKNOWN; + if (run_loop_) + run_loop_->Quit(); + } + + private: + // Stores the event types of the received gesture events. + base::flat_set<ui::EventType> received_event_types_; + ui::EventType wait_for_event_ = ui::EventType::ET_UNKNOWN; + std::unique_ptr<base::RunLoop> run_loop_; +}; + +} // namespace + +class BackGestureBrowserTest : public InProcessBrowserTest { + public: + BackGestureBrowserTest() = default; + BackGestureBrowserTest(const BackGestureBrowserTest&) = delete; + BackGestureBrowserTest& operator=(const BackGestureBrowserTest&) = delete; + ~BackGestureBrowserTest() override = default; + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + base::FilePath test_data_dir; + ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir)); + embedded_test_server()->ServeFilesFromDirectory( + test_data_dir.AppendASCII("chrome/test/data/ash/back_gesture")); + ASSERT_TRUE(embedded_test_server()->Start()); + + // Enter tablet mode. + ash::ShellTestApi().SetTabletModeEnabledForTest(true); + ASSERT_TRUE(ash::TabletMode::Get()->InTabletMode()); + } + + content::RenderWidgetHost* GetRenderWidgetHost() { + return browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetRenderWidgetHostView() + ->GetRenderWidgetHost(); + } + + // Navigate to |url| and wait until browser thread is synchronized with render + // thread. It's needed so that the touch action is correctly initialized. + void NavigateToURLAndWaitForMainFrame(const GURL& url) { + ui_test_utils::NavigateToURL(browser(), url); + content::MainThreadFrameObserver frame_observer(GetRenderWidgetHost()); + frame_observer.Wait(); + } +}; + +// Test back gesture behavior with different touch actions. +IN_PROC_BROWSER_TEST_F(BackGestureBrowserTest, TouchActions) { + // Navigate to a page with {touch-action: none} defined. + NavigateToURLAndWaitForMainFrame( + embedded_test_server()->GetURL("/page_touch_action_none.html")); + ASSERT_EQ(browser()->tab_strip_model()->count(), 1); + + aura::Window* browser_window = browser()->window()->GetNativeWindow(); + const gfx::Rect bounds = browser()->window()->GetBounds(); + const gfx::Point start_point = bounds.left_center(); + const gfx::Point end_point = + gfx::Point(start_point.x() + 200, start_point.y()); + + BackGestureEventRecorder recorder; + browser_window->AddPreTargetHandler(&recorder); + + ui::test::EventGenerator event_generator(browser_window->GetRootWindow(), + browser_window); + event_generator.set_current_screen_location(start_point); + event_generator.PressTouch(); + event_generator.MoveTouch(end_point); + event_generator.ReleaseTouch(); + recorder.WaitUntilReceivedGestureEvent(ui::EventType::ET_GESTURE_END); + + // BackGestureEventHandler did not handle gesture scroll events, so |recorder| + // should be able to get the scroll events. + EXPECT_TRUE(recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_TAP_DOWN)); + EXPECT_TRUE( + recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_SCROLL_BEGIN)); + EXPECT_TRUE( + recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_SCROLL_UPDATE)); + EXPECT_TRUE(recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_SCROLL_END) || + recorder.HasReceivedEvent(ui::EventType::ET_SCROLL_FLING_START)); + // ui::VKEY_BROWSR_BACK key pressed and key released will not be generated + // because back operation is not performed. + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_KEY_PRESSED)); + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_KEY_RELEASED)); + + recorder.Reset(); + + // Now navigate to a page with {touch-action: auto} defined. + NavigateToURLAndWaitForMainFrame( + embedded_test_server()->GetURL("/page_touch_action_auto.html")); + + event_generator.set_current_screen_location(start_point); + event_generator.PressTouch(); + event_generator.MoveTouch(end_point); + event_generator.ReleaseTouch(); + recorder.WaitUntilReceivedGestureEvent(ui::EventType::ET_GESTURE_END); + + // BackGestureEventHandler has handled gesture scroll events, so |recorder| + // should not be able to get the scroll events. + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_TAP_DOWN)); + EXPECT_FALSE( + recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_SCROLL_BEGIN)); + EXPECT_FALSE( + recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_SCROLL_UPDATE)); + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_GESTURE_SCROLL_END)); + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_SCROLL_FLING_START)); + // ui::VKEY_BROWSR_BACK key pressed and key released will be generated because + // back operation can be performed. + EXPECT_TRUE(recorder.HasReceivedEvent(ui::EventType::ET_KEY_PRESSED)); + EXPECT_TRUE(recorder.HasReceivedEvent(ui::EventType::ET_KEY_RELEASED)); + browser_window->RemovePreTargetHandler(&recorder); +} + +// Test the back gesture behavior on page that has prevented default touch +// behavior. +IN_PROC_BROWSER_TEST_F(BackGestureBrowserTest, PreventDefault) { + NavigateToURLAndWaitForMainFrame( + embedded_test_server()->GetURL("/page_prevent_default.html")); + ASSERT_EQ(browser()->tab_strip_model()->count(), 1); + + aura::Window* browser_window = browser()->window()->GetNativeWindow(); + const gfx::Rect bounds = browser()->window()->GetBounds(); + BackGestureEventRecorder recorder; + browser_window->AddPreTargetHandler(&recorder); + + // Start drag on the page that prevents default touch behavior. + const gfx::Point start_point = bounds.left_center(); + const gfx::Point end_point = + gfx::Point(start_point.x() + 200, start_point.y()); + ui::test::EventGenerator event_generator(browser_window->GetRootWindow(), + browser_window); + event_generator.set_current_screen_location(start_point); + event_generator.PressTouch(); + event_generator.MoveTouch(end_point); + event_generator.ReleaseTouch(); + recorder.WaitUntilReceivedGestureEvent(ui::EventType::ET_GESTURE_END); + + // ui::VKEY_BROWSR_BACK key pressed and key released will not be generated + // because back operation is not performed. + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_KEY_PRESSED)); + EXPECT_FALSE(recorder.HasReceivedEvent(ui::EventType::ET_KEY_RELEASED)); + browser_window->RemovePreTargetHandler(&recorder); +}
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index e4e5f264..f82f549e 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -32,6 +32,8 @@ #include "chromeos/services/multidevice_setup/multidevice_setup_service.h" #include "content/public/browser/device_service.h" #include "content/public/browser/media_session_service.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "ui/aura/window.h" #include "url/gurl.h" @@ -40,6 +42,17 @@ const char kKeyboardShortcutHelpPageUrl[] = "https://support.google.com/chromebook/answer/183101"; +content::WebContents* GetActiveWebContentsForNativeBrowserWindow( + gfx::NativeWindow window) { + if (!window) + return nullptr; + BrowserView* browser_view = + BrowserView::GetBrowserViewForNativeWindow(window); + if (!browser_view) + return nullptr; + return browser_view->browser()->tab_strip_model()->GetActiveWebContents(); +} + } // namespace ChromeShellDelegate::ChromeShellDelegate() = default; @@ -63,15 +76,41 @@ } bool ChromeShellDelegate::CanGoBack(gfx::NativeWindow window) const { - BrowserView* browser_view = - BrowserView::GetBrowserViewForNativeWindow(window); - if (!browser_view) - return false; content::WebContents* contents = - browser_view->browser()->tab_strip_model()->GetActiveWebContents(); + GetActiveWebContentsForNativeBrowserWindow(window); + return contents ? contents->GetController().CanGoBack() : false; +} + +bool ChromeShellDelegate::AllowDefaultTouchActions(gfx::NativeWindow window) { + content::WebContents* contents = + GetActiveWebContentsForNativeBrowserWindow(window); + if (!contents) + return true; + content::RenderWidgetHostView* render_widget_host_view = + contents->GetRenderWidgetHostView(); + if (!render_widget_host_view) + return true; + content::RenderWidgetHost* render_widget_host = + render_widget_host_view->GetRenderWidgetHost(); + if (!render_widget_host) + return true; + base::Optional<cc::TouchAction> allowed_touch_action = + render_widget_host->GetAllowedTouchAction(); + return allowed_touch_action.has_value() + ? *allowed_touch_action != cc::TouchAction::kNone + : true; +} + +bool ChromeShellDelegate::ShouldWaitForTouchPressAck(gfx::NativeWindow window) { + content::WebContents* contents = + GetActiveWebContentsForNativeBrowserWindow(window); if (!contents) return false; - return contents->GetController().CanGoBack(); + content::RenderWidgetHostView* render_widget_host_view = + contents->GetRenderWidgetHostView(); + if (!render_widget_host_view) + return false; + return !!render_widget_host_view->GetRenderWidgetHost(); } bool ChromeShellDelegate::IsTabDrag(const ui::OSExchangeData& drop_data) {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index ff3b095f..94475336 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -24,6 +24,8 @@ ash::BackGestureContextualNudgeController* controller) override; void OpenKeyboardShortcutHelpPage() const override; bool CanGoBack(gfx::NativeWindow window) const override; + bool AllowDefaultTouchActions(gfx::NativeWindow window) override; + bool ShouldWaitForTouchPressAck(gfx::NativeWindow window) override; bool IsTabDrag(const ui::OSExchangeData& drop_data) override; aura::Window* CreateBrowserForTabDrop( aura::Window* source_window,
diff --git a/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc b/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc new file mode 100644 index 0000000..430a4d7a --- /dev/null +++ b/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.cc
@@ -0,0 +1,72 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h" + +#include "build/build_config.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/common/chrome_render_frame.mojom.h" +#include "components/blocked_content/popup_navigation_delegate.h" +#include "content/public/browser/web_contents.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom.h" + +#if defined(OS_ANDROID) +#include "chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#endif + +ChromePopupNavigationDelegate::ChromePopupNavigationDelegate( + NavigateParams params) + : params_(std::move(params)), + original_user_gesture_(params_.user_gesture) {} + +content::RenderFrameHost* ChromePopupNavigationDelegate::GetOpener() { + return params_.opener; +} + +bool ChromePopupNavigationDelegate::GetOriginalUserGesture() { + return original_user_gesture_; +} + +const GURL& ChromePopupNavigationDelegate::GetURL() { + return params_.url; +} + +blocked_content::PopupNavigationDelegate::NavigateResult +ChromePopupNavigationDelegate::NavigateWithGesture( + const blink::mojom::WindowFeatures& window_features, + base::Optional<WindowOpenDisposition> updated_disposition) { + params_.user_gesture = true; + if (updated_disposition) + params_.disposition = updated_disposition.value(); +#if defined(OS_ANDROID) + TabModelList::HandlePopupNavigation(¶ms_); +#else + ::Navigate(¶ms_); +#endif + if (params_.navigated_or_inserted_contents && + params_.disposition == WindowOpenDisposition::NEW_POPUP) { + content::RenderFrameHost* host = + params_.navigated_or_inserted_contents->GetMainFrame(); + DCHECK(host); + mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame> client; + host->GetRemoteAssociatedInterfaces()->GetInterface(&client); + client->SetWindowFeatures(window_features.Clone()); + } + return NavigateResult{params_.navigated_or_inserted_contents, + params_.disposition}; +} + +void ChromePopupNavigationDelegate::OnPopupBlocked( + content::WebContents* web_contents, + int total_popups_blocked_on_page) { +#if defined(OS_ANDROID) + // Should replace existing popup infobars, with an updated count of how many + // popups have been blocked. + PopupBlockedInfoBarDelegate::Create(web_contents, + total_popups_blocked_on_page); +#endif +}
diff --git a/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h b/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h new file mode 100644 index 0000000..ab11623 --- /dev/null +++ b/chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h
@@ -0,0 +1,33 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_CHROME_POPUP_NAVIGATION_DELEGATE_H_ +#define CHROME_BROWSER_UI_BLOCKED_CONTENT_CHROME_POPUP_NAVIGATION_DELEGATE_H_ + +#include "chrome/browser/ui/browser_navigator_params.h" +#include "components/blocked_content/popup_navigation_delegate.h" + +class ChromePopupNavigationDelegate + : public blocked_content::PopupNavigationDelegate { + public: + explicit ChromePopupNavigationDelegate(NavigateParams params); + + // blocked_content::PopupNavigationDelegate: + content::RenderFrameHost* GetOpener() override; + bool GetOriginalUserGesture() override; + const GURL& GetURL() override; + NavigateResult NavigateWithGesture( + const blink::mojom::WindowFeatures& window_features, + base::Optional<WindowOpenDisposition> updated_disposition) override; + void OnPopupBlocked(content::WebContents* web_contents, + int total_popups_blocked_on_page) override; + + NavigateParams* nav_params() { return ¶ms_; } + + private: + NavigateParams params_; + bool original_user_gesture_; +}; + +#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_CHROME_POPUP_NAVIGATION_DELEGATE_H_
diff --git a/chrome/browser/ui/blocked_content/popup_blocker.h b/chrome/browser/ui/blocked_content/popup_blocker.h deleted file mode 100644 index 2b3a09d..0000000 --- a/chrome/browser/ui/blocked_content/popup_blocker.h +++ /dev/null
@@ -1,50 +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. - -#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUP_BLOCKER_H_ -#define CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUP_BLOCKER_H_ - -#include "third_party/blink/public/mojom/window_features/window_features.mojom-forward.h" -#include "ui/base/window_open_disposition.h" -#include "url/gurl.h" - -namespace content { -class WebContents; -struct OpenURLParams; -} // namespace content - -struct NavigateParams; - -// Classifies what caused a popup to be blocked. -enum class PopupBlockType { - kNotBlocked, - - // Popup blocked due to no user gesture. - kNoGesture, - // Popup blocked due to the abusive popup blocker. - kAbusive, -}; - -// Whether a new window opened with |disposition| would be considered for -// popup blocking. Note that this includes more dispositions than just -// NEW_POPUP since the popup blocker targets all new windows and tabs. -bool ConsiderForPopupBlocking(WindowOpenDisposition disposition); - -// Returns true if the popup request defined by |params| and the optional -// |open_url_params| should be blocked. In that case, it is also added to the -// |blocked_popups_| container. -// -// |opener_url| is an optional parameter used to compute how the popup -// permission will behave. If it is nullptr, the current committed URL will be -// used instead. -// -// If this function returns true, then the contents of |params| is moved to -// |blocked_popups_|. -bool MaybeBlockPopup(content::WebContents* web_contents, - const GURL* opener_url, - NavigateParams* params, - const content::OpenURLParams* open_url_params, - const blink::mojom::WindowFeatures& window_features); - -#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUP_BLOCKER_H_
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc index 70cb7eb..16edf9a 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_browsertest.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/printing/print_preview_dialog_controller.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" @@ -38,6 +37,7 @@ #include "chrome/test/base/search_test_utils.h" #include "chrome/test/base/ui_test_utils.h" #include "components/blocked_content/list_item_position.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/embedder_support/switches.h" #include "components/javascript_dialogs/app_modal_dialog_controller.h" @@ -146,8 +146,8 @@ ADD_FAILURE() << "Failed to execute script in active tab."; return -1; } - PopupBlockerTabHelper* popup_blocker_helper = - PopupBlockerTabHelper::FromWebContents(tab); + blocked_content::PopupBlockerTabHelper* popup_blocker_helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(tab); return popup_blocker_helper->GetBlockedPopupsCount(); } @@ -222,8 +222,8 @@ ui_test_utils::TabAddedWaiter tab_add(browser); // Launch the blocked popup. - PopupBlockerTabHelper* popup_blocker_helper = - PopupBlockerTabHelper::FromWebContents(web_contents); + blocked_content::PopupBlockerTabHelper* popup_blocker_helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); ui_test_utils::WaitForViewVisibility(browser, VIEW_ID_CONTENT_SETTING_POPUP, true); EXPECT_EQ(1u, popup_blocker_helper->GetBlockedPopupsCount()); @@ -310,7 +310,8 @@ EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture(web_contents, "test()")); EXPECT_EQ(4, GetBlockedContentsCount()); - auto* popup_blocker = PopupBlockerTabHelper::FromWebContents(web_contents); + auto* popup_blocker = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); std::vector<int32_t> ids; for (const auto& it : popup_blocker->GetBlockedPopupRequests()) ids.push_back(it.first); @@ -361,13 +362,17 @@ tester.ExpectBucketCount( kPopupActions, - static_cast<int>(PopupBlockerTabHelper::Action::kInitiated), 2); + static_cast<int>( + blocked_content::PopupBlockerTabHelper::Action::kInitiated), + 2); tester.ExpectBucketCount( - kPopupActions, static_cast<int>(PopupBlockerTabHelper::Action::kBlocked), + kPopupActions, + static_cast<int>( + blocked_content::PopupBlockerTabHelper::Action::kBlocked), 2); // Click through one of them. - auto* popup_blocker = PopupBlockerTabHelper::FromWebContents( + auto* popup_blocker = blocked_content::PopupBlockerTabHelper::FromWebContents( browser()->tab_strip_model()->GetActiveWebContents()); popup_blocker->ShowBlockedPopup( popup_blocker->GetBlockedPopupRequests().begin()->first, @@ -375,7 +380,8 @@ tester.ExpectBucketCount( kPopupActions, - static_cast<int>(PopupBlockerTabHelper::Action::kClickedThroughNoGesture), + static_cast<int>(blocked_content::PopupBlockerTabHelper::Action:: + kClickedThroughNoGesture), 1); // Whitelist the site and navigate again. @@ -385,7 +391,9 @@ ui_test_utils::NavigateToURL(browser(), url); tester.ExpectBucketCount( kPopupActions, - static_cast<int>(PopupBlockerTabHelper::Action::kInitiated), 4); + static_cast<int>( + blocked_content::PopupBlockerTabHelper::Action::kInitiated), + 4); // 4 initiated popups, 2 blocked, and 1 clicked through. tester.ExpectTotalCount(kPopupActions, 4 + 2 + 1); }
diff --git a/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc b/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc index be0677b8..39d376c5 100644 --- a/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/popup_tracker_browsertest.cc
@@ -13,7 +13,6 @@ #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/test_safe_browsing_database_helper.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -21,6 +20,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/browser/tab_specific_content_settings.h" #include "components/safe_browsing/core/db/v4_embedded_test_server_util.h" #include "components/safe_browsing/core/db/v4_test_util.h" @@ -297,7 +297,8 @@ // Click through to open the popup. content::TestNavigationObserver navigation_observer(nullptr, 1); navigation_observer.StartWatchingNewWebContents(); - auto* popup_blocker = PopupBlockerTabHelper::FromWebContents(web_contents); + auto* popup_blocker = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); popup_blocker->ShowBlockedPopup( popup_blocker->GetBlockedPopupRequests().begin()->first, WindowOpenDisposition::NEW_FOREGROUND_TAB);
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc index 218f4ea..f25713eb 100644 --- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc +++ b/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/test_safe_browsing_database_helper.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -28,6 +27,7 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/browser/tab_specific_content_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_types.h" @@ -422,7 +422,7 @@ // Click through. content::TestNavigationObserver navigation_observer(nullptr, 1); navigation_observer.StartWatchingNewWebContents(); - auto* popup_blocker = PopupBlockerTabHelper::FromWebContents( + auto* popup_blocker = blocked_content::PopupBlockerTabHelper::FromWebContents( browser()->tab_strip_model()->GetActiveWebContents()); popup_blocker->ShowBlockedPopup( popup_blocker->GetBlockedPopupRequests().begin()->first, @@ -431,7 +431,8 @@ const char kPopupActions[] = "ContentSettings.Popups.BlockerActions"; tester.ExpectBucketCount( kPopupActions, - static_cast<int>(PopupBlockerTabHelper::Action::kClickedThroughAbusive), + static_cast<int>(blocked_content::PopupBlockerTabHelper::Action:: + kClickedThroughAbusive), 1); navigation_observer.Wait();
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index cfd4013b..d797f8f 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -91,9 +91,8 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" +#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h" #include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/bluetooth/bluetooth_chooser_controller.h" #include "chrome/browser/ui/bluetooth/bluetooth_chooser_desktop.h" #include "chrome/browser/ui/bluetooth/bluetooth_scanning_prompt_controller.h" @@ -157,6 +156,8 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/blocked_content/list_item_position.h" +#include "components/blocked_content/popup_blocker.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/blocked_content/popup_tracker.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" @@ -226,6 +227,7 @@ #include "third_party/blink/public/mojom/frame/blocked_navigation_types.mojom.h" #include "third_party/blink/public/mojom/frame/fullscreen.mojom.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/window_open_disposition.h" #include "ui/gfx/font_list.h" @@ -1599,24 +1601,36 @@ nav_params.tabstrip_add_types = TabStripModel::ADD_NONE; if (params.user_gesture) nav_params.window_action = NavigateParams::SHOW_WINDOW; - bool is_popup = source && ConsiderForPopupBlocking(params.disposition); - if (is_popup && MaybeBlockPopup(source, nullptr, &nav_params, ¶ms, - blink::mojom::WindowFeatures())) { - return nullptr; + bool is_popup = + source && blocked_content::ConsiderForPopupBlocking(params.disposition); + auto popup_delegate = + std::make_unique<ChromePopupNavigationDelegate>(std::move(nav_params)); + if (is_popup) { + popup_delegate.reset(static_cast<ChromePopupNavigationDelegate*>( + blocked_content::MaybeBlockPopup( + source, nullptr, std::move(popup_delegate), ¶ms, + blink::mojom::WindowFeatures(), + HostContentSettingsMapFactory::GetForProfile( + source->GetBrowserContext())) + .release())); + if (!popup_delegate) + return nullptr; } - chrome::ConfigureTabGroupForNavigation(&nav_params); + chrome::ConfigureTabGroupForNavigation(popup_delegate->nav_params()); - Navigate(&nav_params); + Navigate(popup_delegate->nav_params()); - if (is_popup && nav_params.navigated_or_inserted_contents) { + content::WebContents* navigated_or_inserted_contents = + popup_delegate->nav_params()->navigated_or_inserted_contents; + if (is_popup && navigated_or_inserted_contents) { auto* tracker = blocked_content::PopupTracker::CreateForWebContents( - nav_params.navigated_or_inserted_contents, source, params.disposition); + navigated_or_inserted_contents, source, params.disposition); tracker->set_is_trusted(params.triggering_event_info != blink::TriggeringEventInfo::kFromUntrustedEvent); } - return nav_params.navigated_or_inserted_contents; + return navigated_or_inserted_contents; } void Browser::NavigationStateChanged(WebContents* source, @@ -1670,7 +1684,7 @@ // At this point the |new_contents| is beyond the popup blocker, but we use // the same logic for determining if the popup tracker needs to be attached. - if (source && ConsiderForPopupBlocking(disposition)) { + if (source && blocked_content::ConsiderForPopupBlocking(disposition)) { blocked_content::PopupTracker::CreateForWebContents(new_contents.get(), source, disposition); }
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 358b4055..f287c32 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/plugins/plugin_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/collected_cookies_infobar_delegate.h" #include "chrome/browser/ui/content_settings/content_setting_bubble_model_delegate.h" #include "chrome/common/chrome_features.h" @@ -44,6 +43,7 @@ #include "chrome/common/render_messages.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/browser/content_settings_usages_state.h" #include "components/content_settings/browser/tab_specific_content_settings.h" #include "components/content_settings/common/content_settings_agent.mojom.h" @@ -972,7 +972,8 @@ set_title(l10n_util::GetStringUTF16(IDS_BLOCKED_POPUPS_TITLE)); // Build blocked popup list. - auto* helper = PopupBlockerTabHelper::FromWebContents(web_contents); + auto* helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); std::map<int32_t, GURL> blocked_popups = helper->GetBlockedPopupRequests(); for (const auto& blocked_popup : blocked_popups) AddListItem(CreateUrlListItem(blocked_popup.first, blocked_popup.second)); @@ -989,7 +990,8 @@ void ContentSettingPopupBubbleModel::OnListItemClicked(int index, int event_flags) { - auto* helper = PopupBlockerTabHelper::FromWebContents(web_contents()); + auto* helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents()); helper->ShowBlockedPopup(item_id_from_item_index(index), ui::DispositionFromEventFlags(event_flags)); RemoveListItem(index);
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc index 00fbfeb..1485e1b 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -19,8 +19,8 @@ #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" #include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" +#include "chrome/browser/ui/blocked_content/blocked_window_params.h" +#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h" #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" #include "chrome/browser/ui/content_settings/fake_owner.h" #include "chrome/common/chrome_features.h" @@ -29,6 +29,8 @@ #include "chrome/grit/generated_resources.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" +#include "components/blocked_content/popup_blocker.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/browser/tab_specific_content_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" @@ -1270,7 +1272,7 @@ TabSpecificContentSettings::FromWebContents(web_contents()); content_settings->OnContentBlocked(ContentSettingsType::POPUPS); - PopupBlockerTabHelper::CreateForWebContents(web_contents()); + blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents()); std::unique_ptr<ContentSettingBubbleModel> content_setting_bubble_model( ContentSettingBubbleModel::CreateContentSettingBubbleModel( nullptr, web_contents(), ContentSettingsType::POPUPS)); @@ -1286,9 +1288,12 @@ for (size_t i = 1; i <= kItemCount; i++) { NavigateParams navigate_params = params.CreateNavigateParams(web_contents()); - EXPECT_TRUE(MaybeBlockPopup(web_contents(), &url, &navigate_params, - nullptr /*=open_url_params*/, - params.features())); + EXPECT_FALSE(blocked_content::MaybeBlockPopup( + web_contents(), &url, + std::make_unique<ChromePopupNavigationDelegate>( + std::move(navigate_params)), + nullptr /*=open_url_params*/, params.features(), + HostContentSettingsMapFactory::GetForProfile(profile()))); EXPECT_EQ(i, list_items.size()); } }
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 2d675a83..7b34ab4 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -71,7 +71,6 @@ #include "chrome/browser/tab_contents/navigation_metrics_recorder.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/find_bar/find_bar_state.h" #include "chrome/browser/ui/focus_tab_after_navigation_helper.h" #include "chrome/browser/ui/navigation_correction_tab_observer.h" @@ -91,6 +90,7 @@ #include "chrome/common/chrome_switches.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/blocked_content/popup_opener_tab_helper.h" #include "components/captive_portal/core/buildflags.h" #include "components/client_hints/browser/client_hints.h" @@ -283,7 +283,7 @@ permissions::PermissionRequestManager::CreateForWebContents(web_contents); // The PopupBlockerTabHelper has an implicit dependency on // ChromeSubresourceFilterClient being available in its constructor. - PopupBlockerTabHelper::CreateForWebContents(web_contents); + blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents); blocked_content::PopupOpenerTabHelper::CreateForWebContents( web_contents, base::DefaultTickClock::GetInstance(), HostContentSettingsMapFactory::GetForProfile(profile));
diff --git a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc index 5f3c23b..65f22c3 100644 --- a/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc
@@ -11,7 +11,6 @@ #include "chrome/browser/content_settings/tab_specific_content_settings_delegate.h" #include "chrome/browser/download/download_request_limiter.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/content_settings/content_setting_image_model.h" @@ -24,6 +23,7 @@ #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/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/browser/tab_specific_content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" #include "components/permissions/notification_permission_ui_selector.h" @@ -144,7 +144,8 @@ browser(), embedded_test_server()->GetURL("/popup_blocker/popup-many-10.html")); EXPECT_TRUE(content::ExecuteScript(web_contents, std::string())); - auto* helper = PopupBlockerTabHelper::FromWebContents(web_contents); + auto* helper = + blocked_content::PopupBlockerTabHelper::FromWebContents(web_contents); // popup-many-10.html should generate 10 blocked popups. EXPECT_EQ(10u, helper->GetBlockedPopupsCount()); break;
diff --git a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc index c83aff9..71e1d4f 100644 --- a/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc +++ b/chrome/browser/ui/views/media_router/presentation_receiver_window_view.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" #include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/media_router/presentation_receiver_window_delegate.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/search/search_tab_helper.h" @@ -30,6 +29,7 @@ #include "chrome/browser/ui/views/media_router/presentation_receiver_window_frame.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include "components/content_settings/browser/tab_specific_content_settings.h" #include "components/omnibox/browser/location_bar_model_impl.h" #include "content/public/browser/web_contents.h" @@ -162,7 +162,7 @@ ChromeSubresourceFilterClient::CreateForWebContents(web_contents); InfoBarService::CreateForWebContents(web_contents); MixedContentSettingsTabHelper::CreateForWebContents(web_contents); - PopupBlockerTabHelper::CreateForWebContents(web_contents); + blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents); content_settings::TabSpecificContentSettings::CreateForWebContents( web_contents, std::make_unique<chrome::TabSpecificContentSettingsDelegate>(
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 eee3eeef..296ac333 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
@@ -33,6 +33,7 @@ #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 "components/lookalikes/core/features.h" #include "components/safe_browsing/core/db/v4_protocol_manager_util.h" #include "components/security_interstitials/core/common_string_util.h" #include "components/security_state/core/features.h" @@ -234,7 +235,9 @@ {{"topsites", "true"}, {"editdistance", "true"}, {"editdistance_siteengagement", "true"}, - {"targetembedding", "true"}}}}, + {"targetembedding", "true"}}}, + {lookalikes::features::kDetectTargetEmbeddingLookalikes, + {{"enhanced_protection_enabled", "true"}}}}, {}); }
diff --git a/chrome/browser/ui/views/tabs/tab_controller.h b/chrome/browser/ui/views/tabs/tab_controller.h index 009211a..6b670221 100644 --- a/chrome/browser/ui/views/tabs/tab_controller.h +++ b/chrome/browser/ui/views/tabs/tab_controller.h
@@ -124,8 +124,8 @@ // will cause the tab hover card to be hidden. virtual void UpdateHoverCard(Tab* tab) = 0; - // Returns whether domain/origin should be shown in the tab hover card. - virtual bool ShowDomainInHoverCard(const Tab* tab) const = 0; + // Returns whether domain/origin should be shown in tab hover cards. + virtual bool ShowDomainInHoverCards() const = 0; // Returns true if the hover card is showing for the given tab. virtual bool HoverCardIsShowingForTab(Tab* tab) = 0;
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc index a9625eda..5fb0dce 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_bubble_view.cc
@@ -51,7 +51,7 @@ namespace { // Maximum number of lines that a title label occupies. -int kTitleMaxLines = 2; +constexpr int kHoverCardTitleMaxLines = 2; bool AreHoverCardImagesEnabled() { return base::FeatureList::IsEnabled(features::kTabHoverCardImages); @@ -389,11 +389,7 @@ title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); title_label_->SetVerticalAlignment(gfx::ALIGN_TOP); title_label_->SetMultiLine(true); - title_label_->SetMaxLines(kTitleMaxLines); - title_label_->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kPreferred, true)); + title_label_->SetMaxLines(kHoverCardTitleMaxLines); title_fade_label_ = AddChildView(std::make_unique<FadeLabel>( base::string16(), CONTEXT_TAB_HOVER_CARD_TITLE, @@ -401,7 +397,7 @@ title_fade_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); title_fade_label_->SetVerticalAlignment(gfx::ALIGN_TOP); title_fade_label_->SetMultiLine(true); - title_fade_label_->SetMaxLines(kTitleMaxLines); + title_fade_label_->SetMaxLines(kHoverCardTitleMaxLines); domain_label_ = AddChildView(std::make_unique<views::Label>( base::string16(), CONTEXT_BODY_TEXT_LARGE, views::style::STYLE_SECONDARY, @@ -428,6 +424,8 @@ preview_image_->SetPreferredSize(preview_size); } + // Set up layout. + views::FlexLayout* const layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); layout->SetOrientation(views::LayoutOrientation::kVertical); @@ -437,14 +435,31 @@ layout->SetChildViewIgnoredByLayout(title_fade_label_, true); layout->SetChildViewIgnoredByLayout(domain_fade_label_, true); - constexpr int kVerticalMargin = 10; constexpr int kHorizontalMargin = 18; - layout->SetInteriorMargin(gfx::Insets(kVerticalMargin, kHorizontalMargin)); + constexpr int kVerticalMargin = 10; + + gfx::Insets title_margins(kVerticalMargin, kHorizontalMargin); + + // In some browser types (e.g. ChromeOS terminal app) we hide the domain + // label. In those cases, we need to adjust the bottom margin of the title + // element because it is no longer above another text element and needs a + // bottom margin. + const bool show_domain = tab->controller()->ShowDomainInHoverCards(); + domain_label_->SetVisible(show_domain); + if (show_domain) { + title_margins.set_bottom(0); + domain_label_->SetProperty( + views::kMarginsKey, + gfx::Insets(0, kHorizontalMargin, kVerticalMargin, kHorizontalMargin)); + } + + title_label_->SetProperty(views::kMarginsKey, title_margins); title_label_->SetProperty( views::kFlexBehaviorKey, views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum, views::MaximumFlexSizeRule::kPreferred)); - domain_label_->SetVisible(tab->controller()->ShowDomainInHoverCard(tab)); + + // Set up widget. widget_ = views::BubbleDialogDelegateView::CreateBubble(this); set_adjust_if_offscreen(true);
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 3031a132..875d14a 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -1840,7 +1840,7 @@ hover_card_->FadeOutToHide(); } -bool TabStrip::ShowDomainInHoverCard(const Tab* tab) const { +bool TabStrip::ShowDomainInHoverCards() const { const auto* app_controller = controller_->GetBrowser()->app_controller(); return !app_controller || !app_controller->is_for_system_web_app(); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index aa1e8b8c..c7ff212 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -290,7 +290,7 @@ void OnMouseEventInTab(views::View* source, const ui::MouseEvent& event) override; void UpdateHoverCard(Tab* tab) override; - bool ShowDomainInHoverCard(const Tab* tab) const override; + bool ShowDomainInHoverCards() const override; bool HoverCardIsShowingForTab(Tab* tab) override; int GetBackgroundOffset() const override; int GetStrokeThickness() const override;
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc index 6b9b288..347d8cc 100644 --- a/chrome/browser/ui/views/tabs/tab_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_unittest.cc
@@ -87,7 +87,7 @@ void OnMouseEventInTab(views::View* source, const ui::MouseEvent& event) override {} void UpdateHoverCard(Tab* tab) override {} - bool ShowDomainInHoverCard(const Tab* tab) const override { return true; } + bool ShowDomainInHoverCards() const override { return true; } bool HoverCardIsShowingForTab(Tab* tab) override { return false; } int GetBackgroundOffset() const override { return 0; } bool ShouldPaintAsActiveFrame() const override { return true; }
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.cc b/chrome/browser/ui/webui/chromeos/network_ui.cc index da91385d..b04bdf6 100644 --- a/chrome/browser/ui/webui/chromeos/network_ui.cc +++ b/chrome/browser/ui/webui/chromeos/network_ui.cc
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/strings/stringprintf.h" #include "base/values.h" +#include "chrome/browser/chromeos/net/network_health/network_health_service.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/ui/webui/chromeos/cellular_setup/cellular_setup_dialog_launcher.h" #include "chrome/browser/ui/webui/chromeos/internet_config_dialog.h" @@ -22,6 +23,8 @@ #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/generated_resources.h" +#include "chrome/grit/network_health_resources.h" +#include "chrome/grit/network_health_resources_map.h" #include "chromeos/network/device_state.h" #include "chromeos/network/network_configuration_handler.h" #include "chromeos/network/network_device_handler.h" @@ -35,6 +38,7 @@ #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "content/public/browser/web_ui_message_handler.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/cros_system_api/dbus/service_constants.h" #include "ui/base/l10n/l10n_util.h" @@ -347,6 +351,9 @@ "networkListsLabel", l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_LISTS)); localized_strings->SetString( + "networkHealthLabel", + l10n_util::GetStringUTF16(IDS_NETWORK_UI_NETWORK_HEALTH)); + localized_strings->SetString( "visibleNetworksLabel", l10n_util::GetStringUTF16(IDS_NETWORK_UI_VISIBLE_NETWORKS)); localized_strings->SetString( @@ -396,6 +403,10 @@ html->UseStringsJs(); html->AddResourcePath("network_ui.css", IDR_NETWORK_UI_CSS); html->AddResourcePath("network_ui.js", IDR_NETWORK_UI_JS); + html->AddResourcePath("mojo/network_health/network_health.mojom.html", + IDR_NETWORK_HEALTH_MOJOM_HTML); + html->AddResourcePath("mojo/network_health/network_health.mojom-lite.js", + IDR_NETWORK_HEALTH_MOJOM_LITE_JS); html->SetDefaultResource(IDR_NETWORK_UI_HTML); content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(), @@ -409,6 +420,13 @@ ash::GetNetworkConfigService(std::move(receiver)); } +void NetworkUI::BindInterface( + mojo::PendingReceiver<network_health::mojom::NetworkHealthService> + receiver) { + network_health::NetworkHealthService::GetInstance()->BindRemote( + std::move(receiver)); +} + WEB_UI_CONTROLLER_TYPE_IMPL(NetworkUI) } // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/network_ui.h b/chrome/browser/ui/webui/chromeos/network_ui.h index 8e4fc29..49b5d6f 100644 --- a/chrome/browser/ui/webui/chromeos/network_ui.h +++ b/chrome/browser/ui/webui/chromeos/network_ui.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_WEBUI_CHROMEOS_NETWORK_UI_H_ #include "base/macros.h" +#include "chrome/browser/chromeos/net/network_health/public/mojom/network_health.mojom-forward.h" #include "chromeos/services/network_config/public/mojom/cros_network_config.mojom-forward.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "ui/webui/mojo_web_ui_controller.h" @@ -24,11 +25,17 @@ static void GetLocalizedStrings(base::DictionaryValue* localized_strings); - // Instantiates implementor of the mojom::CrosNetworkConfig mojo interface + // Instantiates implementation of the mojom::CrosNetworkConfig mojo interface // passing the pending receiver that will be internally bound. void BindInterface( mojo::PendingReceiver<network_config::mojom::CrosNetworkConfig> receiver); + // Instantiates implementation of the mojom::NetworkHealthService mojo + // interface passing the pending receiver that will be bound. + void BindInterface( + mojo::PendingReceiver<network_health::mojom::NetworkHealthService> + receiver); + private: WEB_UI_CONTROLLER_TYPE_DECL();
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc index 8335dee..831c737 100644 --- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -254,8 +254,8 @@ if (!prefs->GetBoolean(prefs::kClearPluginLSODataEnabled)) site_data_mask &= ~ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PLUGIN_DATA; - int remove_mask = 0; - int origin_mask = 0; + uint64_t remove_mask = 0; + uint64_t origin_mask = 0; std::vector<BrowsingDataType> data_type_vector; const base::ListValue* data_type_list = nullptr; CHECK(args->GetList(1, &data_type_list));
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index c5d2c61..f0ac00d 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -772,6 +772,7 @@ static constexpr webui::LocalizedString kLocalizedStrings[] = { {"autofillPageTitle", IDS_SETTINGS_AUTOFILL}, {"passwords", IDS_SETTINGS_PASSWORDS}, + {"passwordsDevice", IDS_SETTINGS_DEVICE_PASSWORDS}, {"checkPasswords", IDS_SETTINGS_CHECK_PASSWORDS}, {"checkPasswordsCanceled", IDS_SETTINGS_CHECK_PASSWORDS_CANCELED}, {"checkedPasswords", IDS_SETTINGS_CHECKED_PASSWORDS}, @@ -878,6 +879,10 @@ IDS_SETTINGS_PASSWORDS_LEAK_DETECTION_SIGNED_OUT_ENABLED_DESC}, {"savedPasswordsHeading", IDS_SETTINGS_PASSWORDS_SAVED_HEADING}, {"passwordExceptionsHeading", IDS_SETTINGS_PASSWORDS_EXCEPTIONS_HEADING}, + {"deviceOnlyPasswordsHeading", + IDS_SETTINGS_DEVICE_PASSWORDS_ON_DEVICE_ONLY_HEADING}, + {"deviceAndAccountPasswordsHeading", + IDS_SETTINGS_DEVICE_PASSWORDS_ON_DEVICE_AND_ACCOUNT_HEADING}, {"deletePasswordException", IDS_SETTINGS_PASSWORDS_DELETE_EXCEPTION}, {"removePassword", IDS_SETTINGS_PASSWORD_REMOVE}, {"searchPasswords", IDS_SETTINGS_PASSWORD_SEARCH}, @@ -895,6 +900,8 @@ {"editPasswordPasswordLabel", IDS_SETTINGS_PASSWORDS_PASSWORD}, {"noAddressesFound", IDS_SETTINGS_ADDRESS_NONE}, {"noPasswordsFound", IDS_SETTINGS_PASSWORDS_NONE}, + {"devicePasswordsEmptySubsectionText", + IDS_SETTINGS_DEVICE_PASSWORDS_EMPTY_SUBSECTION_TEXT}, {"noExceptionsFound", IDS_SETTINGS_PASSWORDS_EXCEPTIONS_NONE}, {"import", IDS_PASSWORD_MANAGER_IMPORT_BUTTON}, {"exportMenuItem", IDS_SETTINGS_PASSWORDS_EXPORT_MENU_ITEM},
diff --git a/chrome/browser/web_applications/components/pending_app_manager.cc b/chrome/browser/web_applications/components/pending_app_manager.cc index 091b67a4..e34219b 100644 --- a/chrome/browser/web_applications/components/pending_app_manager.cc +++ b/chrome/browser/web_applications/components/pending_app_manager.cc
@@ -40,12 +40,14 @@ AppShortcutManager* shortcut_manager, FileHandlerManager* file_handler_manager, WebAppUiManager* ui_manager, - InstallFinalizer* finalizer) { + InstallFinalizer* finalizer, + InstallManager* install_manager) { registrar_ = registrar; shortcut_manager_ = shortcut_manager; file_handler_manager_ = file_handler_manager; ui_manager_ = ui_manager; finalizer_ = finalizer; + install_manager_ = install_manager; } void PendingAppManager::SynchronizeInstalledApps(
diff --git a/chrome/browser/web_applications/components/pending_app_manager.h b/chrome/browser/web_applications/components/pending_app_manager.h index ae71b98..253bf77 100644 --- a/chrome/browser/web_applications/components/pending_app_manager.h +++ b/chrome/browser/web_applications/components/pending_app_manager.h
@@ -27,6 +27,7 @@ class AppShortcutManager; class FileHandlerManager; class InstallFinalizer; +class InstallManager; class WebAppUiManager; enum class RegistrationResultCode { kSuccess, kAlreadyRegistered, kTimeout }; @@ -60,7 +61,8 @@ AppShortcutManager* shortcut_manager, FileHandlerManager* file_handler_manager, WebAppUiManager* ui_manager, - InstallFinalizer* finalizer); + InstallFinalizer* finalizer, + InstallManager* install_manager); // Queues an installation operation with the highest priority. Essentially // installing the app immediately if there are no ongoing operations or @@ -121,6 +123,7 @@ FileHandlerManager* file_handler_manager() { return file_handler_manager_; } WebAppUiManager* ui_manager() { return ui_manager_; } InstallFinalizer* finalizer() { return finalizer_; } + InstallManager* install_manager() { return install_manager_; } virtual void OnRegistrationFinished(const GURL& launch_url, RegistrationResultCode result); @@ -155,6 +158,7 @@ FileHandlerManager* file_handler_manager_ = nullptr; WebAppUiManager* ui_manager_ = nullptr; InstallFinalizer* finalizer_ = nullptr; + InstallManager* install_manager_ = nullptr; base::flat_map<ExternalInstallSource, SynchronizeRequest> synchronize_requests_;
diff --git a/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc b/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc index 3e12ee9..25d0c1d 100644 --- a/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
@@ -330,6 +330,7 @@ TestWebAppUiManager* ui_manager() { return ui_manager_; } TestAppRegistrar* registrar() { return registrar_; } TestPendingAppInstallFinalizer* finalizer() { return install_finalizer_; } + WebAppInstallManager* install_manager() { return install_manager_; } TestAppShortcutManager* shortcut_manager() { return shortcut_manager_; } TestFileHandlerManager* file_handler_manager() { return file_handler_manager_; @@ -372,7 +373,7 @@ auto task = std::make_unique<PendingAppInstallTask>( profile(), registrar_, shortcut_manager_, file_handler_manager_, - ui_manager_, install_finalizer_, std::move(options)); + ui_manager_, install_finalizer_, install_manager_, std::move(options)); return task; } @@ -902,7 +903,7 @@ ExternalInstallSource::kInternalDefault); PendingAppInstallTask install_task( profile(), registrar(), shortcut_manager(), file_handler_manager(), - ui_manager(), finalizer(), install_options); + ui_manager(), finalizer(), install_manager(), install_options); install_task.Install( web_contents(), result_pair.loader_result, @@ -919,9 +920,9 @@ ExternalInstallOptions install_options( GURL(), DisplayMode::kStandalone, ExternalInstallSource::kInternalDefault); - PendingAppInstallTask install_task(profile(), registrar(), shortcut_manager(), - file_handler_manager(), ui_manager(), - finalizer(), install_options); + PendingAppInstallTask install_task( + profile(), registrar(), shortcut_manager(), file_handler_manager(), + ui_manager(), finalizer(), install_manager(), install_options); install_task.Install( web_contents(), WebAppUrlLoader::Result::kFailedWebContentsDestroyed,
diff --git a/chrome/browser/web_applications/pending_app_install_task.cc b/chrome/browser/web_applications/pending_app_install_task.cc index eb5b2778..debcea7 100644 --- a/chrome/browser/web_applications/pending_app_install_task.cc +++ b/chrome/browser/web_applications/pending_app_install_task.cc
@@ -22,7 +22,6 @@ #include "chrome/browser/web_applications/components/install_finalizer.h" #include "chrome/browser/web_applications/components/install_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" -#include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/components/web_app_ui_manager.h" #include "chrome/common/web_application_info.h" #include "components/performance_manager/embedder/performance_manager_registry.h" @@ -59,12 +58,14 @@ FileHandlerManager* file_handler_manager, WebAppUiManager* ui_manager, InstallFinalizer* install_finalizer, + InstallManager* install_manager, ExternalInstallOptions install_options) : profile_(profile), registrar_(registrar), shortcut_manager_(shortcut_manager), file_handler_manager_(file_handler_manager), install_finalizer_(install_finalizer), + install_manager_(install_manager), ui_manager_(ui_manager), externally_installed_app_prefs_(profile_->GetPrefs()), install_options_(std::move(install_options)) {} @@ -169,14 +170,12 @@ void PendingAppInstallTask::ContinueWebAppInstall( content::WebContents* web_contents, ResultCallback result_callback) { - auto* provider = WebAppProviderBase::GetProviderBase(profile_); - DCHECK(provider); auto install_params = ConvertExternalInstallOptionsToParams(install_options_); auto install_source = ConvertExternalInstallSourceToInstallSource( install_options_.install_source); - provider->install_manager().InstallWebAppWithParams( + install_manager_->InstallWebAppWithParams( web_contents, install_params, install_source, base::BindOnce(&PendingAppInstallTask::OnWebAppInstalled, weak_ptr_factory_.GetWeakPtr(), false /* is_placeholder */,
diff --git a/chrome/browser/web_applications/pending_app_install_task.h b/chrome/browser/web_applications/pending_app_install_task.h index a2ad4e13..271e3b99 100644 --- a/chrome/browser/web_applications/pending_app_install_task.h +++ b/chrome/browser/web_applications/pending_app_install_task.h
@@ -28,6 +28,7 @@ class AppShortcutManager; class FileHandlerManager; class InstallFinalizer; +class InstallManager; class WebAppUiManager; enum class InstallResultCode; @@ -62,6 +63,7 @@ FileHandlerManager* file_handler_manager, WebAppUiManager* ui_manager, InstallFinalizer* install_finalizer, + InstallManager* install_manager, ExternalInstallOptions install_options); virtual ~PendingAppInstallTask(); @@ -95,6 +97,7 @@ AppShortcutManager* const shortcut_manager_; FileHandlerManager* const file_handler_manager_; InstallFinalizer* const install_finalizer_; + InstallManager* const install_manager_; WebAppUiManager* const ui_manager_; ExternallyInstalledWebAppPrefs externally_installed_app_prefs_;
diff --git a/chrome/browser/web_applications/pending_app_manager_impl.cc b/chrome/browser/web_applications/pending_app_manager_impl.cc index 3f7315c9..874ac75 100644 --- a/chrome/browser/web_applications/pending_app_manager_impl.cc +++ b/chrome/browser/web_applications/pending_app_manager_impl.cc
@@ -101,7 +101,7 @@ ExternalInstallOptions install_options) { return std::make_unique<PendingAppInstallTask>( profile_, registrar(), shortcut_manager(), file_handler_manager(), - ui_manager(), finalizer(), std::move(install_options)); + ui_manager(), finalizer(), install_manager(), std::move(install_options)); } std::unique_ptr<PendingAppRegistrationTaskBase>
diff --git a/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc b/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc index 8c87c7c..f00b5c5 100644 --- a/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc +++ b/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc
@@ -218,6 +218,7 @@ pending_app_manager_impl->file_handler_manager(), pending_app_manager_impl->ui_manager(), pending_app_manager_impl->finalizer(), + pending_app_manager_impl->install_manager(), install_options), pending_app_manager_impl_(pending_app_manager_impl), externally_installed_app_prefs_(profile->GetPrefs()) {}
diff --git a/chrome/browser/web_applications/test/test_pending_app_manager.cc b/chrome/browser/web_applications/test/test_pending_app_manager.cc index 71bfc71..d30bed9 100644 --- a/chrome/browser/web_applications/test/test_pending_app_manager.cc +++ b/chrome/browser/web_applications/test/test_pending_app_manager.cc
@@ -24,7 +24,7 @@ deduped_uninstall_count_(0), registrar_(registrar) { // TODO(crbug.com/973324): Wire this up to a TestInstallFinalizer. - SetSubsystems(registrar, nullptr, nullptr, nullptr, nullptr); + SetSubsystems(registrar, nullptr, nullptr, nullptr, nullptr, nullptr); } TestPendingAppManager::~TestPendingAppManager() = default;
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index f3252ac4..90b6593 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -258,7 +258,7 @@ install_manager_.get(), system_web_app_manager_.get()); pending_app_manager_->SetSubsystems( registrar_.get(), shortcut_manager_.get(), file_handler_manager_.get(), - ui_manager_.get(), install_finalizer_.get()); + ui_manager_.get(), install_finalizer_.get(), install_manager_.get()); external_web_app_manager_->SetSubsystems(pending_app_manager_.get()); system_web_app_manager_->SetSubsystems( pending_app_manager_.get(), registrar_.get(), registry_controller_.get(),
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 902cf5e..e257c12 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-master-1591199990-53a8f554cee1144b8cf9ac7f99b06fbe1ec5521a.profdata +chrome-mac-master-1591214254-6aa4e5b3c8cad7acd58b53b8c7cc7024959b4c99.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index d0b4a75..88819f4 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-master-1591184865-5178b7a96ecfc255ba5ba33ed0277fd9a93edec8.profdata +chrome-win64-master-1591214254-82dbd7c2e7bf4bdc6dd6038655b6e3a5aff423fd.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 026e671..6ff33889 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -159,6 +159,7 @@ "$root_gen_dir/chrome/camera_resources.pak", "$root_gen_dir/chrome/cellular_setup_resources.pak", "$root_gen_dir/chrome/multidevice_setup_resources.pak", + "$root_gen_dir/chrome/network_health_resources.pak", "$root_gen_dir/chrome/os_settings_resources.pak", "$root_gen_dir/chromeos/chromeos_help_app_bundle_resources.pak", "$root_gen_dir/chromeos/chromeos_help_app_resources.pak", @@ -175,6 +176,7 @@ "//chrome/browser/resources/chromeos:camera_resources", "//chrome/browser/resources/chromeos:cellular_setup_resources", "//chrome/browser/resources/chromeos:multidevice_setup_resources", + "//chrome/browser/resources/chromeos:network_health_resources", "//chrome/browser/supervised_user:supervised_user_unscaled_resources", "//chromeos/resources", "//chromeos/resources:help_app_bundle_resources",
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 4f4c508..76b8d094 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2404,6 +2404,7 @@ "../browser/ui/app_list/chrome_app_list_model_updater_browsertest.cc", "../browser/ui/ash/accelerator_commands_browsertest.cc", "../browser/ui/ash/assistant/assistant_context_browsertest.cc", + "../browser/ui/ash/back_gesture_browsertest.cc", "../browser/ui/ash/chrome_new_window_client_browsertest.cc", "../browser/ui/ash/chrome_screenshot_grabber_browsertest.cc", "../browser/ui/ash/keyboard/keyboard_controller_browsertest.cc", @@ -3454,7 +3455,6 @@ "../browser/ui/android/tab_model/tab_model_list_unittest.cc", "../browser/ui/android/toolbar/location_bar_model_android_unittest.cc", "../browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc", - "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc", "../browser/ui/chrome_select_file_policy_unittest.cc", "../browser/ui/cookie_controls/cookie_controls_controller_unittest.cc", "../browser/ui/cookie_controls/cookie_controls_service_unittest.cc",
diff --git a/chrome/test/data/ash/back_gesture/page_prevent_default.html b/chrome/test/data/ash/back_gesture/page_prevent_default.html new file mode 100644 index 0000000..970bb82 --- /dev/null +++ b/chrome/test/data/ash/back_gesture/page_prevent_default.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<style> +body { + position: absolute; + width: 100%; + height: 100%; + margin: 0; + padding: 0; +} +#prevent_default_id { + width: 100%; + height: 100%; +} +</style> +<body> + <div id="prevent_default_id"></div> +<script> +document.querySelector("#prevent_default_id").addEventListener( + "touchmove", function(e) { e.preventDefault(); }); +</script> +</body> +</html>
diff --git a/chrome/test/data/ash/back_gesture/page_touch_action_default.html b/chrome/test/data/ash/back_gesture/page_touch_action_default.html new file mode 100644 index 0000000..18b01a7b --- /dev/null +++ b/chrome/test/data/ash/back_gesture/page_touch_action_default.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<style> +body { + position: absolute; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + touch-action: auto; +} +</style> +<body> +</body> +</html>
diff --git a/chrome/test/data/ash/back_gesture/page_touch_action_none.html b/chrome/test/data/ash/back_gesture/page_touch_action_none.html new file mode 100644 index 0000000..b6d6ce8 --- /dev/null +++ b/chrome/test/data/ash/back_gesture/page_touch_action_none.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<style> +body { + position: absolute; + width: 100%; + height: 100%; + margin: 0; + padding: 0; + touch-action: none; +} +</style> +<body> +</body> +</html>
diff --git a/chrome/test/data/printing/bug_806746_new.emf b/chrome/test/data/printing/bug_806746_new.emf new file mode 100644 index 0000000..27dea90 --- /dev/null +++ b/chrome/test/data/printing/bug_806746_new.emf Binary files differ
diff --git a/chrome/test/data/printing/pdf_converter_basic_ps_new_page_1.emf b/chrome/test/data/printing/pdf_converter_basic_ps_new_page_1.emf new file mode 100644 index 0000000..20fe31e --- /dev/null +++ b/chrome/test/data/printing/pdf_converter_basic_ps_new_page_1.emf Binary files differ
diff --git a/chrome/test/data/printing/pdf_converter_basic_ps_new_page_2.emf b/chrome/test/data/printing/pdf_converter_basic_ps_new_page_2.emf new file mode 100644 index 0000000..d6a1ba8 --- /dev/null +++ b/chrome/test/data/printing/pdf_converter_basic_ps_new_page_2.emf Binary files differ
diff --git a/chrome/test/data/printing/pdf_converter_basic_ps_new_page_3.emf b/chrome/test/data/printing/pdf_converter_basic_ps_new_page_3.emf new file mode 100644 index 0000000..da1b2d3d --- /dev/null +++ b/chrome/test/data/printing/pdf_converter_basic_ps_new_page_3.emf Binary files differ
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index a3595d5..9784082 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -5,313 +5,316 @@ import("//build/config/crypto.gni") import("//chrome/common/features.gni") import("//chrome/test/base/js2gtest.gni") +import("//chrome/test/include_js_tests.gni") import("//third_party/closure_compiler/compile_js.gni") import("//ui/webui/resources/tools/js_modulizer.gni") import("./namespace_rewrites.gni") -js2gtest("interactive_ui_tests_js_webui") { - test_type = "webui" +if (include_js_tests) { + js2gtest("interactive_ui_tests_js_webui") { + test_type = "webui" - sources = [ - "bookmarks/bookmarks_focus_test.js", - "cr_elements/cr_elements_focus_test.js", - "cr_elements/cr_elements_v3_focus_test.js", - "cr_focus_outline_manager_test.js", - "cr_focus_row_behavior_interactive_test.js", - "cr_focus_row_behavior_v3_interactive_test.js", - "extensions/cr_extensions_interactive_ui_tests.js", - "history/history_focus_test.js", - "new_tab_page/new_tab_page_interactive_test.js", - "print_preview/print_preview_interactive_ui_tests.js", - "settings/cr_settings_v3_interactive_ui_tests.js", - ] - - gen_include_files = [ - "polymer_browser_test_base.js", - "polymer_interactive_ui_test.js", - ] - - deps = [ - ":modulize", - "//chrome/browser/ui", - ] - data = [ - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_action_menu_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_checkbox_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_expand_button_focus_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_icon_button_focus_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_input_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_tabs_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toggle_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/iron_list_focus_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_focus_row_behavior_test.m.js", - "$root_gen_dir/chrome/test/data/webui/mock_controller.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/sync_test_util.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/test_sync_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/test_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/test_store.m.js", - "$root_gen_dir/chrome/test/data/webui/test_util.m.js", - ] - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] -} - -js2gtest("browser_tests_js_webui") { - test_type = "webui" - - # Javascript sources. These are combined with the .cc files in the GYP build - # and are handled by a rule, but in the GN build they're in a separate - # action so need to be separated out. - sources = [ - "../../../browser/ui/webui/identity_internals_ui_browsertest.js", - "../../../browser/ui/webui/sync_internals_browsertest.js", - "about_invalidations_browsertest.js", - "assertions.js", - "async_gen.js", - "bookmarks/bookmarks_browsertest.js", - "chrome_send_browsertest.js", - "cr_components/cr_components_browsertest.js", - "cr_components/cr_components_v3_browsertest.js", - "cr_elements/cr_elements_browsertest.js", - "cr_elements/cr_elements_v3_browsertest.js", - "find_shortcut_behavior_browsertest.js", - "find_shortcut_behavior_v3_browsertest.js", - "histograms/histograms_internals_ui_browsertest.js", - "history/history_browsertest.js", - "js/webui_resource_module_async_browsertest.js", - "js2gtest_browsertest.js", - "load_time_data_browsertest.js", - "management/a11y/management_a11y_test.js", - "mock4js_browsertest.js", - "net_internals/chromeos_view.js", - "net_internals/dns_view.js", - "net_internals/domain_security_policy_view.js", - "net_internals/main.js", - "net_internals/net_internals_test.js", - "ntp4.js", - "resources/webui_resources_browsertest.js", - "resources/webui_resources_v3_browsertest.js", - "sandboxstatus_browsertest.js", - "settings/a11y/v3_a11y_browsertest.js", - "settings/cr_settings_v3_browsertest.js", - "settings/settings_idle_load_v3_browsertest.js", - "text_defaults_browsertest.js", - "webui_resource_async_browsertest.js", - ] - - gen_include_files = [ - "a11y/accessibility_audit_rules.js", - "a11y/accessibility_test.js", - "polymer_browser_test_base.js", - "settings/a11y/settings_accessibility_v3_test.js", - "//third_party/axe-core/axe.js", - ] - - if (is_chromeos) { - gen_include_files += [ - "settings/chromeos/a11y/os_settings_accessibility_test.js", - "settings/chromeos/a11y/crostini_accessibility_test.js", + sources = [ + "bookmarks/bookmarks_focus_test.js", + "cr_elements/cr_elements_focus_test.js", + "cr_elements/cr_elements_v3_focus_test.js", + "cr_focus_outline_manager_test.js", + "cr_focus_row_behavior_interactive_test.js", + "cr_focus_row_behavior_v3_interactive_test.js", + "extensions/cr_extensions_interactive_ui_tests.js", + "history/history_focus_test.js", + "new_tab_page/new_tab_page_interactive_test.js", + "print_preview/print_preview_interactive_ui_tests.js", + "settings/cr_settings_v3_interactive_ui_tests.js", ] + + gen_include_files = [ + "polymer_browser_test_base.js", + "polymer_interactive_ui_test.js", + ] + + deps = [ + ":modulize", + "//chrome/browser/ui", + ] + data = [ + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_action_menu_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_checkbox_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_expand_button_focus_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_icon_button_focus_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_input_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_profile_avatar_selector_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_tabs_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toggle_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/iron_list_focus_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_focus_row_behavior_test.m.js", + "$root_gen_dir/chrome/test/data/webui/mock_controller.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/sync_test_util.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_sync_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/test_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/test_store.m.js", + "$root_gen_dir/chrome/test/data/webui/test_util.m.js", + ] + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] } - extra_js_files = [ - "test_browser_proxy.js", - "settings/test_password_manager_proxy.js", - "settings/passwords_and_autofill_fake_data.js", - "//chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js", - "//chrome/browser/ui/webui/chromeos/account_manager/account_manager_proxy_test.js", - ] + js2gtest("browser_tests_js_webui") { + test_type = "webui" - if (is_chromeos) { - sources += [ - "../../../browser/resources/chromeos/login/security_token_pin_browsertest.js", - "../../../browser/ui/webui/chromeos/account_manager/account_migration_welcome_test.js", - "../../../browser/ui/webui/chromeos/bluetooth_pairing_dialog_browsertest.js", - "../../../browser/ui/webui/chromeos/certificate_manager_dialog_browsertest.js", - "../chromeos/oobe_webui_browsertest.js", - "chromeos/edu_login/edu_login_browsertest.js", - "set_time_dialog_browsertest.js", - "settings/chromeos/a11y/crostini_settings_details_a11y_test.js", - "settings/chromeos/a11y/crostini_settings_export_import_a11y_test.js", - "settings/chromeos/a11y/crostini_settings_shared_paths_a11y_test.js", - "settings/chromeos/a11y/crostini_settings_shared_usb_devices_a11y_test.js", - "settings/chromeos/a11y/crostini_settings_subpage_a11y_test.js", - "settings/chromeos/a11y/google_assistant_a11y_test.js", - "settings/chromeos/a11y/manage_accessibility_a11y_test.js", - "settings/chromeos/a11y/multidevice_a11y_test.js", - "settings/chromeos/a11y/multidevice_features_a11y_test.js", - "settings/chromeos/a11y/tts_subpage_a11y_test.js", - "settings/chromeos/os_settings_browsertest.js", - "settings/chromeos/os_settings_ui_browsertest.js", - "sys_internals/sys_internals_browsertest.js", + # Javascript sources. These are combined with the .cc files in the GYP build + # and are handled by a rule, but in the GN build they're in a separate + # action so need to be separated out. + sources = [ + "../../../browser/ui/webui/identity_internals_ui_browsertest.js", + "../../../browser/ui/webui/sync_internals_browsertest.js", + "about_invalidations_browsertest.js", + "assertions.js", + "async_gen.js", + "bookmarks/bookmarks_browsertest.js", + "chrome_send_browsertest.js", + "cr_components/cr_components_browsertest.js", + "cr_components/cr_components_v3_browsertest.js", + "cr_elements/cr_elements_browsertest.js", + "cr_elements/cr_elements_v3_browsertest.js", + "find_shortcut_behavior_browsertest.js", + "find_shortcut_behavior_v3_browsertest.js", + "histograms/histograms_internals_ui_browsertest.js", + "history/history_browsertest.js", + "js/webui_resource_module_async_browsertest.js", + "js2gtest_browsertest.js", + "load_time_data_browsertest.js", + "management/a11y/management_a11y_test.js", + "mock4js_browsertest.js", + "net_internals/chromeos_view.js", + "net_internals/dns_view.js", + "net_internals/domain_security_policy_view.js", + "net_internals/main.js", + "net_internals/net_internals_test.js", + "ntp4.js", + "resources/webui_resources_browsertest.js", + "resources/webui_resources_v3_browsertest.js", + "sandboxstatus_browsertest.js", + "settings/a11y/v3_a11y_browsertest.js", + "settings/cr_settings_v3_browsertest.js", + "settings/settings_idle_load_v3_browsertest.js", + "text_defaults_browsertest.js", + "webui_resource_async_browsertest.js", ] - if (!optimize_webui) { - sources += [ "settings/chromeos/os_settings_v3_browsertest.js" ] + + gen_include_files = [ + "a11y/accessibility_audit_rules.js", + "a11y/accessibility_test.js", + "polymer_browser_test_base.js", + "settings/a11y/settings_accessibility_v3_test.js", + "//third_party/axe-core/axe.js", + ] + + if (is_chromeos) { + gen_include_files += [ + "settings/chromeos/a11y/os_settings_accessibility_test.js", + "settings/chromeos/a11y/crostini_accessibility_test.js", + ] } - } else { - sources += [ - "signin/signin_browsertest.js", - "user_manager/user_manager_browsertest.js", - "welcome/a11y_tests.js", - "welcome/welcome_browsertest.js", + + extra_js_files = [ + "test_browser_proxy.js", + "settings/test_password_manager_proxy.js", + "settings/passwords_and_autofill_fake_data.js", + "//chrome/browser/resources/signin/sync_confirmation/sync_confirmation_browser_proxy.js", + "//chrome/browser/ui/webui/chromeos/account_manager/account_manager_proxy_test.js", ] - } - if (use_nss_certs) { - sources += [ "certificate_viewer_dialog_browsertest.js" ] - } - if (enable_extensions) { - sources += [ - "extensions/a11y/extensions_a11y_test.js", - "extensions/cr_extensions_browsertest.js", + if (is_chromeos) { + sources += [ + "../../../browser/resources/chromeos/login/security_token_pin_browsertest.js", + "../../../browser/ui/webui/chromeos/account_manager/account_migration_welcome_test.js", + "../../../browser/ui/webui/chromeos/bluetooth_pairing_dialog_browsertest.js", + "../../../browser/ui/webui/chromeos/certificate_manager_dialog_browsertest.js", + "../chromeos/oobe_webui_browsertest.js", + "chromeos/edu_login/edu_login_browsertest.js", + "set_time_dialog_browsertest.js", + "settings/chromeos/a11y/crostini_settings_details_a11y_test.js", + "settings/chromeos/a11y/crostini_settings_export_import_a11y_test.js", + "settings/chromeos/a11y/crostini_settings_shared_paths_a11y_test.js", + "settings/chromeos/a11y/crostini_settings_shared_usb_devices_a11y_test.js", + "settings/chromeos/a11y/crostini_settings_subpage_a11y_test.js", + "settings/chromeos/a11y/google_assistant_a11y_test.js", + "settings/chromeos/a11y/manage_accessibility_a11y_test.js", + "settings/chromeos/a11y/multidevice_a11y_test.js", + "settings/chromeos/a11y/multidevice_features_a11y_test.js", + "settings/chromeos/a11y/tts_subpage_a11y_test.js", + "settings/chromeos/os_settings_browsertest.js", + "settings/chromeos/os_settings_ui_browsertest.js", + "sys_internals/sys_internals_browsertest.js", + ] + if (!optimize_webui) { + sources += [ "settings/chromeos/os_settings_v3_browsertest.js" ] + } + } else { + sources += [ + "signin/signin_browsertest.js", + "user_manager/user_manager_browsertest.js", + "welcome/a11y_tests.js", + "welcome/welcome_browsertest.js", + ] + } + + if (use_nss_certs) { + sources += [ "certificate_viewer_dialog_browsertest.js" ] + } + if (enable_extensions) { + sources += [ + "extensions/a11y/extensions_a11y_test.js", + "extensions/cr_extensions_browsertest.js", + ] + } + if (enable_print_preview) { + sources += [ "print_preview/print_preview_ui_browsertest.js" ] + } + if (enable_webui_tab_strip) { + sources += [ "tab_strip/tab_strip_browsertest.js" ] + } + deps = [ + ":modulize", + "//build:branding_buildflags", + "//chrome/browser/ui", + "//services/network/public/cpp", + "//skia", ] - } - if (enable_print_preview) { - sources += [ "print_preview/print_preview_ui_browsertest.js" ] - } - if (enable_webui_tab_strip) { - sources += [ "tab_strip/tab_strip_browsertest.js" ] - } - deps = [ - ":modulize", - "//build:branding_buildflags", - "//chrome/browser/ui", - "//services/network/public/cpp", - "//skia", - ] - data = [ - "$root_gen_dir/chrome/test/data/webui/cr_components/managed_footnote_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_button_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_container_shadow_behavior_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_dialog_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_drawer_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_expand_button_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_fingerprint_progress_arc_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_icon_button_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_lazy_render_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_link_row_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_lottie_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_pref_indicator_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_radio_button_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_radio_group_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_search_field_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_scrollable_behavior_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_slider_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_manager_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_test.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_view_manager_test.m.js", - "$root_gen_dir/chrome/test/data/webui/fake_chrome_event.m.js", - "$root_gen_dir/chrome/test/data/webui/find_shortcut_behavior_test.m.js", - "$root_gen_dir/chrome/test/data/webui/mock_controller.m.js", - "$root_gen_dir/chrome/test/data/webui/mock_timer.m.js", - "$root_gen_dir/chrome/test/data/webui/resources/list_property_update_behavior_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/fake_input_method_private.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/fake_language_settings_private.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/fake_settings_private.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/pref_util_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/prefs_test_cases.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/prefs_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/settings_slider_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/settings_textarea_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/settings_toggle_button_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/sync_test_util.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/test_languages_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/test_lifetime_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/test_profile_info_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/test_search_engines_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/test_sync_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/test_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/test_store.m.js", - "$root_gen_dir/chrome/test/data/webui/test_util.m.js", - ] - if (is_chromeos) { - data += [ - "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_reset_page_test.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/localized_link_test.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_reset_browser_proxy.m.js", - "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_lifetime_browser_proxy.m.js", + data = [ + "$root_gen_dir/chrome/test/data/webui/cr_components/managed_footnote_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_button_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_container_shadow_behavior_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_dialog_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_drawer_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_expand_button_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_fingerprint_progress_arc_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_icon_button_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_lazy_render_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_link_row_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_lottie_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_indicator_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_policy_pref_indicator_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_radio_button_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_radio_group_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_search_field_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_scrollable_behavior_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_slider_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_manager_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toast_test.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_toolbar_search_field_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_view_manager_test.m.js", + "$root_gen_dir/chrome/test/data/webui/fake_chrome_event.m.js", + "$root_gen_dir/chrome/test/data/webui/find_shortcut_behavior_test.m.js", + "$root_gen_dir/chrome/test/data/webui/mock_controller.m.js", + "$root_gen_dir/chrome/test/data/webui/mock_timer.m.js", + "$root_gen_dir/chrome/test/data/webui/resources/list_property_update_behavior_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/fake_input_method_private.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/fake_language_settings_private.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/fake_settings_private.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/pref_util_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/prefs_test_cases.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/prefs_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/settings_slider_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/settings_textarea_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/settings_toggle_button_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/sync_test_util.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_languages_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_lifetime_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_profile_info_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_search_engines_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/test_sync_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/test_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/test_store.m.js", + "$root_gen_dir/chrome/test/data/webui/test_util.m.js", ] - } - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] -} - -js2gtest("browser_tests_js_mojo_lite_webui") { - test_type = "mojo_lite_webui" - - sources = [ - "bluetooth_internals_browsertest.js", - "downloads/downloads_browsertest.js", - "engagement/site_engagement_browsertest.js", - "interventions_internals_browsertest.js", - "media/media_engagement_browsertest.js", - "media/media_feeds_webui_browsertest.js", - "media/media_history_webui_browsertest.js", - "new_tab_page/new_tab_page_browsertest.js", - "usb_internals_browsertest.js", - ] - - deps = [ "//chrome/browser/ui" ] - - if (is_win || is_mac || is_desktop_linux || is_chromeos) { - sources += [ "discards/discards_browsertest.js" ] + if (is_chromeos) { + data += [ + "$root_gen_dir/chrome/test/data/webui/cr_elements/cr_searchable_drop_down_tests.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_reset_page_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/localized_link_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_reset_browser_proxy.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/test_os_lifetime_browser_proxy.m.js", + ] + } + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] } - if (is_chromeos) { - sources += [ - "chromeos/crostini_installer_browsertest.js", - "chromeos/crostini_upgrader_browsertest.js", - "chromeos/machine_learning_internals_browsertest.js", - "chromeos/print_management/print_management_browsertest.js", - "chromeos/print_management/scanning_page_browsertest.js", - "multidevice_setup/multidevice_setup_browsertest.js", + js2gtest("browser_tests_js_mojo_lite_webui") { + test_type = "mojo_lite_webui" + + sources = [ + "bluetooth_internals_browsertest.js", + "downloads/downloads_browsertest.js", + "engagement/site_engagement_browsertest.js", + "interventions_internals_browsertest.js", + "media/media_engagement_browsertest.js", + "media/media_feeds_webui_browsertest.js", + "media/media_history_webui_browsertest.js", + "new_tab_page/new_tab_page_browsertest.js", + "usb_internals_browsertest.js", ] - deps += [ "//chromeos/services/machine_learning/public/cpp:test_support" ] + + deps = [ "//chrome/browser/ui" ] + + if (is_win || is_mac || is_desktop_linux || is_chromeos) { + sources += [ "discards/discards_browsertest.js" ] + } + + if (is_chromeos) { + sources += [ + "chromeos/crostini_installer_browsertest.js", + "chromeos/crostini_upgrader_browsertest.js", + "chromeos/machine_learning_internals_browsertest.js", + "chromeos/print_management/print_management_browsertest.js", + "chromeos/print_management/scanning_page_browsertest.js", + "multidevice_setup/multidevice_setup_browsertest.js", + ] + deps += [ "//chromeos/services/machine_learning/public/cpp:test_support" ] + } + + extra_js_files = [ "//chrome/browser/resources/downloads/constants.js" ] + + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] } - extra_js_files = [ "//chrome/browser/resources/downloads/constants.js" ] - - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] -} - -js2gtest("unit_tests_js") { - test_type = "unit" - sources = [ - "../../../renderer/resources/extensions/notifications_custom_bindings.gtestjs", - "../unit/framework_unittest.gtestjs", - ] - extra_js_files = [ - "../../../browser/resources/downloads/browser_proxy.js", - "../../../browser/resources/downloads/search_service.js", - "../../../renderer/resources/extensions/notifications_custom_bindings.js", - "../../../renderer/resources/extensions/notifications_test_util.js", - "//ui/webui/resources/js/cr.js", - ] - if (is_chromeos) { - sources += [ - "../../../browser/resources/chromeos/accessibility/braille_ime/braille_ime_unittest.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/node_utils_unittest.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/paragraph_utils_unittest.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/rect_utils_unittest.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_unittest.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/word_utils_unittest.js", - "../../../browser/resources/chromeos/accessibility/switch_access/rect_helper_unittest.js", - "../../../browser/resources/chromeos/machine_learning/machine_learning_internals_utils_unittest.js", + js2gtest("unit_tests_js") { + test_type = "unit" + sources = [ + "../../../renderer/resources/extensions/notifications_custom_bindings.gtestjs", + "../unit/framework_unittest.gtestjs", ] - extra_js_files += [ - "../../../browser/resources/chromeos/accessibility/braille_ime/braille_ime.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/paragraph_utils.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/rect_utils.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/test_support.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/word_utils.js", - "../../../browser/resources/chromeos/accessibility/select_to_speak/node_utils.js", - "../../../browser/resources/chromeos/accessibility/switch_access/rect_helper.js", - "../../../browser/resources/chromeos/machine_learning/machine_learning_internals_utils.js", + extra_js_files = [ + "../../../browser/resources/downloads/browser_proxy.js", + "../../../browser/resources/downloads/search_service.js", + "../../../renderer/resources/extensions/notifications_custom_bindings.js", + "../../../renderer/resources/extensions/notifications_test_util.js", + "//ui/webui/resources/js/cr.js", ] + if (is_chromeos) { + sources += [ + "../../../browser/resources/chromeos/accessibility/braille_ime/braille_ime_unittest.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/node_utils_unittest.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/paragraph_utils_unittest.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/rect_utils_unittest.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/select_to_speak_unittest.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/word_utils_unittest.js", + "../../../browser/resources/chromeos/accessibility/switch_access/rect_helper_unittest.js", + "../../../browser/resources/chromeos/machine_learning/machine_learning_internals_utils_unittest.js", + ] + extra_js_files += [ + "../../../browser/resources/chromeos/accessibility/braille_ime/braille_ime.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/paragraph_utils.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/rect_utils.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/select_to_speak.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/test_support.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/word_utils.js", + "../../../browser/resources/chromeos/accessibility/select_to_speak/node_utils.js", + "../../../browser/resources/chromeos/accessibility/switch_access/rect_helper.js", + "../../../browser/resources/chromeos/machine_learning/machine_learning_internals_utils.js", + ] + } } }
diff --git a/chromeos/components/media_app_ui/resources/js/launch.js b/chromeos/components/media_app_ui/resources/js/launch.js index b49dada..c2b5b924 100644 --- a/chromeos/components/media_app_ui/resources/js/launch.js +++ b/chromeos/components/media_app_ui/resources/js/launch.js
@@ -54,6 +54,15 @@ /** A pipe through which we can send messages to the guest frame. */ const guestMessagePipe = new MessagePipe('chrome-untrusted://media-app'); +/** + * Promise that resolves once the iframe is ready to receive messages. This is + * to allow initial file processing to run in parallel with the iframe load. + * @type {!Promise<undefined>} + */ +const iframeReady = new Promise(resolve => { + guestMessagePipe.registerHandler(Message.IFRAME_READY, resolve); +}); + guestMessagePipe.registerHandler(Message.OPEN_FEEDBACK_DIALOG, () => { let response = mediaAppPageHandler.openFeedbackDialog(); if (response === null) { @@ -284,6 +293,7 @@ for (const fd of snapshot) { fd.file = null; } + await iframeReady; await guestMessagePipe.sendMessage(Message.LOAD_FILES, loadFilesMessage); } @@ -469,9 +479,10 @@ await sendFilesToGuest(); } -// Wait for 'load' (and not DOMContentLoaded) to ensure the subframe has been -// loaded and is ready to respond to postMessage. -window.addEventListener('load', () => { +/** + * Installs the handler for launch files, if window.launchQueue is available. + */ +function installLaunchHandler() { if (!window.launchQueue) { console.error('FileHandling API missing.'); return; @@ -491,4 +502,6 @@ const focusEntry = assertCast(params.files[1]); launchWithDirectory(directory, focusEntry); }); -}); +} + +installLaunchHandler();
diff --git a/chromeos/components/media_app_ui/resources/js/message_types.js b/chromeos/components/media_app_ui/resources/js/message_types.js index e65c146..665c2b6 100644 --- a/chromeos/components/media_app_ui/resources/js/message_types.js +++ b/chromeos/components/media_app_ui/resources/js/message_types.js
@@ -13,6 +13,7 @@ */ const Message = { DELETE_FILE: 'delete-file', + IFRAME_READY: 'iframe-ready', LOAD_FILES: 'load-files', NAVIGATE: 'navigate', OPEN_FEEDBACK_DIALOG: 'open-feedback-dialog',
diff --git a/chromeos/components/media_app_ui/resources/js/receiver.js b/chromeos/components/media_app_ui/resources/js/receiver.js index 4e27c7e..73ca5f93 100644 --- a/chromeos/components/media_app_ui/resources/js/receiver.js +++ b/chromeos/components/media_app_ui/resources/js/receiver.js
@@ -145,6 +145,10 @@ await loadFiles(new ReceivedFileList(filesMessage)); }); +// As soon as the LOAD_FILES handler is installed, signal readiness to the +// parent frame (privileged context). +parentMessagePipe.sendMessage(Message.IFRAME_READY); + /** * A delegate which exposes privileged WebUI functionality to the media * app.
diff --git a/components/BUILD.gn b/components/BUILD.gn index 3be8451..7462d5a 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -221,6 +221,7 @@ "//components/autofill/content/browser:unit_tests", "//components/autofill/content/renderer:unit_tests", "//components/autofill/core/common/mojom:unit_tests", + "//components/blocked_content:unit_tests", "//components/browsing_data/content:unit_tests", "//components/captive_portal/content:unit_tests", "//components/cast_certificate:unit_tests",
diff --git a/components/arc/midis/arc_midis_bridge.cc b/components/arc/midis/arc_midis_bridge.cc index a0edd30..60de5dc0 100644 --- a/components/arc/midis/arc_midis_bridge.cc +++ b/components/arc/midis/arc_midis_bridge.cc
@@ -57,7 +57,7 @@ } void ArcMidisBridge::OnBootstrapMojoConnection( - mojom::MidisServerRequest request, + mojo::PendingReceiver<mojom::MidisServer> receiver, mojom::MidisClientPtr client_ptr, bool result) { if (!result) { @@ -70,14 +70,14 @@ return; } DVLOG(1) << "ArcMidisBridge succeeded with Mojo bootstrapping."; - midis_host_remote_->Connect(std::move(request), std::move(client_ptr)); + midis_host_remote_->Connect(std::move(receiver), std::move(client_ptr)); } -void ArcMidisBridge::Connect(mojom::MidisServerRequest request, +void ArcMidisBridge::Connect(mojo::PendingReceiver<mojom::MidisServer> receiver, mojom::MidisClientPtr client_ptr) { if (midis_host_remote_.is_bound()) { DVLOG(1) << "Re-using bootstrap connection for MidisServer Connect."; - midis_host_remote_->Connect(std::move(request), std::move(client_ptr)); + midis_host_remote_->Connect(std::move(receiver), std::move(client_ptr)); return; } DVLOG(1) << "Bootstrapping the Midis connection via D-Bus."; @@ -101,7 +101,7 @@ ->BootstrapMojoConnection( channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD(), base::BindOnce(&ArcMidisBridge::OnBootstrapMojoConnection, - weak_factory_.GetWeakPtr(), std::move(request), + weak_factory_.GetWeakPtr(), std::move(receiver), std::move(client_ptr))); }
diff --git a/components/arc/midis/arc_midis_bridge.h b/components/arc/midis/arc_midis_bridge.h index 6bfcf7b..501de45d 100644 --- a/components/arc/midis/arc_midis_bridge.h +++ b/components/arc/midis/arc_midis_bridge.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "components/arc/mojom/midis.mojom.h" #include "components/keyed_service/core/keyed_service.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/remote.h" namespace content { @@ -34,13 +35,14 @@ ~ArcMidisBridge() override; // Midis Mojo host interface - void Connect(mojom::MidisServerRequest request, + void Connect(mojo::PendingReceiver<mojom::MidisServer> receiver, mojom::MidisClientPtr client_ptr) override; private: - void OnBootstrapMojoConnection(mojom::MidisServerRequest request, - mojom::MidisClientPtr client_ptr, - bool result); + void OnBootstrapMojoConnection( + mojo::PendingReceiver<mojom::MidisServer> receiver, + mojom::MidisClientPtr client_ptr, + bool result); void OnMojoConnectionError(); ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
diff --git a/components/arc/mojom/midis.mojom b/components/arc/mojom/midis.mojom index 782e49a..54ecbf1 100644 --- a/components/arc/mojom/midis.mojom +++ b/components/arc/mojom/midis.mojom
@@ -66,7 +66,7 @@ // by the client). // Next Method ID: 1 interface MidisHost { - Connect@0(MidisServer& server, MidisClient client); + Connect@0(pending_receiver<MidisServer> server, MidisClient client); }; // MidisInstance is implemented in the ARC MIDI JNI code that
diff --git a/components/arc/mojom/oemcrypto.mojom b/components/arc/mojom/oemcrypto.mojom index 1c905625..c7d050de 100644 --- a/components/arc/mojom/oemcrypto.mojom +++ b/components/arc/mojom/oemcrypto.mojom
@@ -342,7 +342,7 @@ // that runs in Chrome OS. // Next Method ID: 1 interface OemCryptoHost { - Connect@0(OemCryptoService& oemcryptor); + Connect@0(pending_receiver<OemCryptoService> oemcryptor); }; // OemCryptoInstance is implemented in the liboemcrypto.so library that runs in
diff --git a/components/arc/mojom/print_spooler.mojom b/components/arc/mojom/print_spooler.mojom index 4c19715..b0322e7 100644 --- a/components/arc/mojom/print_spooler.mojom +++ b/components/arc/mojom/print_spooler.mojom
@@ -42,11 +42,12 @@ // The |top_margin| is the height of the space at the top of the window. // The returned |host| will be null if errors occur while saving the print // document or locating the Android surface. - [MinVersion=1] StartPrintInCustomTab@0(handle scoped_handle, - int32 task_id, - int32 surface_id, - int32 top_margin, - PrintSessionInstance instance) + [MinVersion=1] StartPrintInCustomTab@0( + handle scoped_handle, + int32 task_id, + int32 surface_id, + int32 top_margin, + pending_remote<PrintSessionInstance> instance) => (PrintSessionHost? host); };
diff --git a/components/blocked_content/BUILD.gn b/components/blocked_content/BUILD.gn index f650c83..d9fd500 100644 --- a/components/blocked_content/BUILD.gn +++ b/components/blocked_content/BUILD.gn
@@ -6,6 +6,11 @@ sources = [ "list_item_position.cc", "list_item_position.h", + "popup_blocker.cc", + "popup_blocker.h", + "popup_blocker_tab_helper.cc", + "popup_blocker_tab_helper.h", + "popup_navigation_delegate.h", "popup_opener_tab_helper.cc", "popup_opener_tab_helper.h", "popup_tracker.cc", @@ -19,9 +24,12 @@ ] deps = [ "//base", + "//components/content_settings/browser", "//components/content_settings/core/browser", + "//components/embedder_support", "//components/pref_registry", "//components/prefs", + "//components/safe_browsing/content/triggers:ad_popup_trigger", "//components/safe_browsing/core/db:util", "//components/subresource_filter/content/browser", "//components/ukm/content", @@ -31,3 +39,23 @@ "//third_party/blink/public/common", ] } + +source_set("unit_tests") { + testonly = true + sources = [ "safe_browsing_triggered_popup_blocker_unittest.cc" ] + deps = [ + ":blocked_content", + "//base", + "//base/test:test_support", + "//components/content_settings/browser", + "//components/content_settings/core/browser", + "//components/subresource_filter/content/browser", + "//components/subresource_filter/content/browser:test_support", + "//components/subresource_filter/core/browser", + "//components/sync_preferences:test_support", + "//components/user_prefs", + "//content/test:test_support", + "//net:test_support", + "//testing/gtest", + ] +}
diff --git a/components/blocked_content/DEPS b/components/blocked_content/DEPS index f76cac1..15f6f7a 100644 --- a/components/blocked_content/DEPS +++ b/components/blocked_content/DEPS
@@ -1,12 +1,17 @@ include_rules = [ + "+components/content_settings/browser", "+components/content_settings/core", + "+components/embedder_support", "+components/pref_registry", "+components/prefs", "+components/safe_browsing", "+components/subresource_filter/content/browser", + "+components/subresource_filter/core/browser", + "+components/sync_preferences", "+components/ukm", "+components/user_prefs", "+content/public/browser", + "+content/public/test", "+services/metrics/public", "+third_party/blink/public", "+ui/base",
diff --git a/chrome/browser/ui/blocked_content/popup_blocker.cc b/components/blocked_content/popup_blocker.cc similarity index 72% rename from chrome/browser/ui/blocked_content/popup_blocker.cc rename to components/blocked_content/popup_blocker.cc index 4459b3a..6b278ac2 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker.cc +++ b/components/blocked_content/popup_blocker.cc
@@ -2,16 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/blocked_content/popup_blocker.h" +#include "components/blocked_content/popup_blocker.h" #include <string> #include "base/check.h" #include "base/command_line.h" -#include "chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" -#include "chrome/browser/ui/browser_navigator_params.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" +#include "components/blocked_content/popup_navigation_delegate.h" #include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings.h" @@ -21,6 +19,7 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +namespace blocked_content { namespace { // If the popup should be blocked, returns the reason why it was blocked. @@ -28,7 +27,8 @@ PopupBlockType ShouldBlockPopup(content::WebContents* web_contents, const GURL* opener_url, bool user_gesture, - const content::OpenURLParams* open_url_params) { + const content::OpenURLParams* open_url_params, + HostContentSettingsMap* settings_map) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( embedder_support::kDisablePopupBlocking)) { return PopupBlockType::kNotBlocked; @@ -42,12 +42,9 @@ // unloading page. const GURL& url = opener_url ? *opener_url : web_contents->GetLastCommittedURL(); - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); if (url.is_valid() && - HostContentSettingsMapFactory::GetForProfile(profile)->GetContentSetting( - url, url, ContentSettingsType::POPUPS, std::string()) == - CONTENT_SETTING_ALLOW) { + settings_map->GetContentSetting(url, url, ContentSettingsType::POPUPS, + std::string()) == CONTENT_SETTING_ALLOW) { return PopupBlockType::kNotBlocked; } @@ -62,8 +59,7 @@ } auto* safe_browsing_blocker = - blocked_content::SafeBrowsingTriggeredPopupBlocker::FromWebContents( - web_contents); + SafeBrowsingTriggeredPopupBlocker::FromWebContents(web_contents); if (safe_browsing_blocker && safe_browsing_blocker->ShouldApplyAbusivePopupBlocker()) { return PopupBlockType::kAbusive; @@ -74,11 +70,11 @@ // Tries to get the opener from either the |params| or |open_url_params|, // otherwise uses the focused frame from |web_contents| as a proxy. content::RenderFrameHost* GetSourceFrameForPopup( - NavigateParams* params, + PopupNavigationDelegate* params, const content::OpenURLParams* open_url_params, content::WebContents* web_contents) { - if (params->opener) - return params->opener; + if (params->GetOpener()) + return params->GetOpener(); // Make sure the source render frame host is alive before we attempt to // retrieve it from |open_url_params|. if (open_url_params) { @@ -102,32 +98,40 @@ disposition == WindowOpenDisposition::NEW_WINDOW; } -bool MaybeBlockPopup(content::WebContents* web_contents, - const GURL* opener_url, - NavigateParams* params, - const content::OpenURLParams* open_url_params, - const blink::mojom::WindowFeatures& window_features) { +std::unique_ptr<PopupNavigationDelegate> MaybeBlockPopup( + content::WebContents* web_contents, + const GURL* opener_url, + std::unique_ptr<PopupNavigationDelegate> delegate, + const content::OpenURLParams* open_url_params, + const blink::mojom::WindowFeatures& window_features, + HostContentSettingsMap* settings_map) { DCHECK(web_contents); DCHECK(!open_url_params || - open_url_params->user_gesture == params->user_gesture); + open_url_params->user_gesture == delegate->GetOriginalUserGesture()); PopupBlockerTabHelper::LogAction(PopupBlockerTabHelper::Action::kInitiated); // Check |popup_blocker| first since it is cheaper than ShouldBlockPopup(). auto* popup_blocker = PopupBlockerTabHelper::FromWebContents(web_contents); if (!popup_blocker) - return false; + return delegate; PopupBlockType block_type = ShouldBlockPopup( - web_contents, opener_url, params->user_gesture, open_url_params); + web_contents, opener_url, delegate->GetOriginalUserGesture(), + open_url_params, settings_map); if (block_type == PopupBlockType::kNotBlocked) - return false; + return delegate; - popup_blocker->AddBlockedPopup(params, window_features, block_type); + // AddBlockedPopup() takes ownership of the delegate, so grab the source frame + // first. + content::RenderFrameHost* source_frame = + GetSourceFrameForPopup(delegate.get(), open_url_params, web_contents); + popup_blocker->AddBlockedPopup(std::move(delegate), window_features, + block_type); auto* trigger = safe_browsing::AdPopupTrigger::FromWebContents(web_contents); if (trigger) { - content::RenderFrameHost* source_frame = - GetSourceFrameForPopup(params, open_url_params, web_contents); trigger->PopupWasBlocked(source_frame); } - return true; + return nullptr; } + +} // namespace blocked_content
diff --git a/components/blocked_content/popup_blocker.h b/components/blocked_content/popup_blocker.h new file mode 100644 index 0000000..be9cc439 --- /dev/null +++ b/components/blocked_content/popup_blocker.h
@@ -0,0 +1,58 @@ +// 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. + +#ifndef COMPONENTS_BLOCKED_CONTENT_POPUP_BLOCKER_H_ +#define COMPONENTS_BLOCKED_CONTENT_POPUP_BLOCKER_H_ + +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom-forward.h" +#include "ui/base/window_open_disposition.h" +#include "url/gurl.h" + +class HostContentSettingsMap; + +namespace content { +class WebContents; +struct OpenURLParams; +} // namespace content + +namespace blocked_content { +class PopupNavigationDelegate; + +// Classifies what caused a popup to be blocked. +enum class PopupBlockType { + kNotBlocked, + + // Popup blocked due to no user gesture. + kNoGesture, + // Popup blocked due to the abusive popup blocker. + kAbusive, +}; + +// Whether a new window opened with |disposition| would be considered for +// popup blocking. Note that this includes more dispositions than just +// NEW_POPUP since the popup blocker targets all new windows and tabs. +bool ConsiderForPopupBlocking(WindowOpenDisposition disposition); + +// Returns null if the popup request defined by |delegate| and the optional +// |open_url_params| should be blocked. In that case, it is also added to the +// |blocked_popups_| container. +// +// |opener_url| is an optional parameter used to compute how the popup +// permission will behave. If it is nullptr, the current committed URL will be +// used instead. +// +// If this function returns a non-null unique_ptr, the navigation was not +// blocked and should be continued. +std::unique_ptr<PopupNavigationDelegate> MaybeBlockPopup( + content::WebContents* web_contents, + const GURL* opener_url, + std::unique_ptr<PopupNavigationDelegate> delegate, + const content::OpenURLParams* open_url_params, + const blink::mojom::WindowFeatures& window_features, + HostContentSettingsMap* settings_map); + +} // namespace blocked_content + +#endif // COMPONENTS_BLOCKED_CONTENT_POPUP_BLOCKER_H_
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc b/components/blocked_content/popup_blocker_tab_helper.cc similarity index 68% rename from chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc rename to components/blocked_content/popup_blocker_tab_helper.cc index 177c543..784bef6 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc +++ b/components/blocked_content/popup_blocker_tab_helper.cc
@@ -2,20 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" #include <iterator> #include <string> #include "base/metrics/histogram_macros.h" #include "build/build_config.h" -#include "chrome/browser/ui/android/content_settings/popup_blocked_infobar_delegate.h" -#include "chrome/browser/ui/blocked_content/blocked_window_params.h" -#include "chrome/browser/ui/browser_navigator.h" -#include "chrome/browser/ui/browser_navigator_params.h" -#include "chrome/common/chrome_render_frame.mojom.h" -#include "chrome/common/render_messages.h" #include "components/blocked_content/list_item_position.h" +#include "components/blocked_content/popup_navigation_delegate.h" #include "components/blocked_content/popup_tracker.h" #include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" #include "components/content_settings/browser/tab_specific_content_settings.h" @@ -26,24 +21,20 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" -#include "mojo/public/cpp/bindings/associated_remote.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom.h" -#if defined(OS_ANDROID) -#include "chrome/browser/ui/android/tab_model/tab_model_list.h" -#endif - +namespace blocked_content { const size_t kMaximumNumberOfPopups = 25; struct PopupBlockerTabHelper::BlockedRequest { - BlockedRequest(NavigateParams&& params, + BlockedRequest(std::unique_ptr<PopupNavigationDelegate> delegate, const blink::mojom::WindowFeatures& window_features, PopupBlockType block_type) - : params(std::move(params)), + : delegate(std::move(delegate)), window_features(window_features), block_type(block_type) {} - NavigateParams params; + std::unique_ptr<PopupNavigationDelegate> delegate; blink::mojom::WindowFeatures window_features; PopupBlockType block_type; }; @@ -53,8 +44,7 @@ blocked_content::SafeBrowsingTriggeredPopupBlocker::MaybeCreate(web_contents); } -PopupBlockerTabHelper::~PopupBlockerTabHelper() { -} +PopupBlockerTabHelper::~PopupBlockerTabHelper() = default; void PopupBlockerTabHelper::DidFinishNavigation( content::NavigationHandle* navigation_handle) { @@ -93,7 +83,7 @@ } void PopupBlockerTabHelper::AddBlockedPopup( - NavigateParams* params, + std::unique_ptr<PopupNavigationDelegate> delegate, const blink::mojom::WindowFeatures& window_features, PopupBlockType block_type) { LogAction(Action::kBlocked); @@ -103,16 +93,13 @@ int id = next_id_; next_id_++; blocked_popups_[id] = std::make_unique<BlockedRequest>( - std::move(*params), window_features, block_type); + std::move(delegate), window_features, block_type); content_settings::TabSpecificContentSettings::FromWebContents(web_contents()) ->OnContentBlocked(ContentSettingsType::POPUPS); - manager_.NotifyObservers(id, blocked_popups_[id]->params.url); + auto* raw_delegate = blocked_popups_[id]->delegate.get(); + manager_.NotifyObservers(id, raw_delegate->GetURL()); -#if defined(OS_ANDROID) - // Should replace existing popup infobars, with an updated count of how many - // popups have been blocked. - PopupBlockedInfoBarDelegate::Create(web_contents(), GetBlockedPopupsCount()); -#endif + raw_delegate->OnPopupBlocked(web_contents(), GetBlockedPopupsCount()); } void PopupBlockerTabHelper::ShowBlockedPopup( @@ -131,30 +118,18 @@ BlockedRequest* popup = it->second.get(); - // We set user_gesture to true here, so the new popup gets correctly focused. - popup->params.user_gesture = true; + base::Optional<WindowOpenDisposition> updated_disposition; if (disposition != WindowOpenDisposition::CURRENT_TAB) - popup->params.disposition = disposition; + updated_disposition = disposition; -#if defined(OS_ANDROID) - TabModelList::HandlePopupNavigation(&popup->params); -#else - Navigate(&popup->params); -#endif - if (popup->params.navigated_or_inserted_contents) { + PopupNavigationDelegate::NavigateResult result = + popup->delegate->NavigateWithGesture(popup->window_features, + updated_disposition); + if (result.navigated_or_inserted_contents) { auto* tracker = blocked_content::PopupTracker::CreateForWebContents( - popup->params.navigated_or_inserted_contents, web_contents(), - popup->params.disposition); + result.navigated_or_inserted_contents, web_contents(), + result.disposition); tracker->set_is_trusted(true); - - if (popup->params.disposition == WindowOpenDisposition::NEW_POPUP) { - content::RenderFrameHost* host = - popup->params.navigated_or_inserted_contents->GetMainFrame(); - DCHECK(host); - mojo::AssociatedRemote<chrome::mojom::ChromeRenderFrame> client; - host->GetRemoteAssociatedInterfaces()->GetInterface(&client); - client->SetWindowFeatures(popup->window_features.Clone()); - } } switch (popup->block_type) { @@ -179,10 +154,10 @@ } PopupBlockerTabHelper::PopupIdMap - PopupBlockerTabHelper::GetBlockedPopupRequests() { +PopupBlockerTabHelper::GetBlockedPopupRequests() { PopupIdMap result; for (const auto& it : blocked_popups_) { - result[it.first] = it.second->params.url; + result[it.first] = it.second->delegate->GetURL(); } return result; } @@ -193,3 +168,5 @@ } WEB_CONTENTS_USER_DATA_KEY_IMPL(PopupBlockerTabHelper) + +} // namespace blocked_content
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h b/components/blocked_content/popup_blocker_tab_helper.h similarity index 87% rename from chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h rename to components/blocked_content/popup_blocker_tab_helper.h index 53a3702b..8d1381f 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h +++ b/components/blocked_content/popup_blocker_tab_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUP_BLOCKER_TAB_HELPER_H_ -#define CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUP_BLOCKER_TAB_HELPER_H_ +#ifndef COMPONENTS_BLOCKED_CONTENT_POPUP_BLOCKER_TAB_HELPER_H_ +#define COMPONENTS_BLOCKED_CONTENT_POPUP_BLOCKER_TAB_HELPER_H_ #include <stddef.h> #include <stdint.h> @@ -12,15 +12,15 @@ #include <memory> #include "base/macros.h" -#include "chrome/browser/ui/blocked_content/blocked_window_params.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" +#include "components/blocked_content/popup_blocker.h" #include "components/blocked_content/url_list_manager.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "ui/base/window_open_disposition.h" #include "url/gurl.h" -struct NavigateParams; +namespace blocked_content { +class PopupNavigationDelegate; // Per-tab class to manage blocked popups. class PopupBlockerTabHelper @@ -65,7 +65,7 @@ void ShowBlockedPopup(int32_t popup_id, WindowOpenDisposition disposition); // Adds a new blocked popup to the UI. - void AddBlockedPopup(NavigateParams* params, + void AddBlockedPopup(std::unique_ptr<PopupNavigationDelegate> delegate, const blink::mojom::WindowFeatures& window_features, PopupBlockType block_type); @@ -100,4 +100,6 @@ DISALLOW_COPY_AND_ASSIGN(PopupBlockerTabHelper); }; -#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_POPUP_BLOCKER_TAB_HELPER_H_ +} // namespace blocked_content + +#endif // COMPONENTS_BLOCKED_CONTENT_POPUP_BLOCKER_TAB_HELPER_H_
diff --git a/components/blocked_content/popup_navigation_delegate.h b/components/blocked_content/popup_navigation_delegate.h new file mode 100644 index 0000000..8c7cb02 --- /dev/null +++ b/components/blocked_content/popup_navigation_delegate.h
@@ -0,0 +1,55 @@ +// Copyright 2020 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_BLOCKED_CONTENT_POPUP_NAVIGATION_DELEGATE_H_ +#define COMPONENTS_BLOCKED_CONTENT_POPUP_NAVIGATION_DELEGATE_H_ + +#include <memory> + +#include "base/optional.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom-forward.h" +#include "ui/base/window_open_disposition.h" + +class GURL; + +namespace content { +class RenderFrameHost; +class WebContents; +} // namespace content + +namespace blocked_content { + +// A delegate interface to allow an embedder specific representation of a +// navigation. This is stored internally in the popup blocker to recover +// navigations when the user clicks through a previously blocked popup. +class PopupNavigationDelegate { + public: + virtual ~PopupNavigationDelegate() = default; + + // Gets the opener used if new WebContents are created for this navigation. + virtual content::RenderFrameHost* GetOpener() = 0; + + // Gets whether the blocked navigation was initiated by a user gesture. + virtual bool GetOriginalUserGesture() = 0; + + // Gets the URL to be loaded. + virtual const GURL& GetURL() = 0; + + // Performs the navigation. + struct NavigateResult { + content::WebContents* navigated_or_inserted_contents = nullptr; + WindowOpenDisposition disposition = WindowOpenDisposition::UNKNOWN; + }; + virtual NavigateResult NavigateWithGesture( + const blink::mojom::WindowFeatures& window_features, + base::Optional<WindowOpenDisposition> updated_disposition) = 0; + + // Called when the navigation represented by this class was blocked. + virtual void OnPopupBlocked(content::WebContents* web_contents, + int total_popups_blocked_on_page) = 0; +}; + +} // namespace blocked_content + +#endif // COMPONENTS_BLOCKED_CONTENT_POPUP_NAVIGATION_DELEGATE_H_
diff --git a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc similarity index 65% rename from chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc rename to components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc index 44ece06..c8667d4 100644 --- a/chrome/browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc +++ b/components/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc
@@ -14,93 +14,152 @@ #include "base/task/post_task.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" -#include "chrome/browser/content_settings/tab_specific_content_settings_delegate.h" -#include "chrome/browser/infobars/infobar_service.h" -#include "chrome/browser/safe_browsing/test_safe_browsing_service.h" -#include "chrome/browser/subresource_filter/chrome_subresource_filter_client.h" -#include "chrome/browser/ui/blocked_content/popup_blocker.h" -#include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" -#include "chrome/browser/ui/browser_navigator_params.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" +#include "components/blocked_content/popup_blocker.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" +#include "components/blocked_content/popup_navigation_delegate.h" #include "components/content_settings/browser/tab_specific_content_settings.h" -#include "components/safe_browsing/core/db/v4_protocol_manager_util.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/subresource_filter/content/browser/fake_safe_browsing_database_manager.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/browser/subresource_filter_safe_browsing_activation_throttle.h" +#include "components/subresource_filter/content/browser/subresource_filter_safe_browsing_client.h" #include "components/subresource_filter/core/browser/subresource_filter_constants.h" -#include "components/subresource_filter/core/browser/subresource_filter_features.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/user_prefs/user_prefs.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle.h" #include "content/public/test/navigation_simulator.h" +#include "content/public/test/test_navigation_throttle_inserter.h" #include "content/public/test/test_renderer_host.h" -#include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/navigation/triggering_event_info.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom.h" #include "ui/base/page_transition_types.h" #include "ui/base/window_open_disposition.h" #include "url/gurl.h" +namespace blocked_content { const char kNumBlockedHistogram[] = "ContentSettings.Popups.StrongBlocker.NumBlocked"; -// TODO(crbug.com/1084013): Move this into //components/blocked_content. -class SafeBrowsingTriggeredPopupBlockerTest - : public ChromeRenderViewHostTestHarness { +class TestPopupNavigationDelegate : public PopupNavigationDelegate { public: - SafeBrowsingTriggeredPopupBlockerTest() {} - ~SafeBrowsingTriggeredPopupBlockerTest() override {} + explicit TestPopupNavigationDelegate(const GURL& url) : url_(url) {} + content::RenderFrameHost* GetOpener() override { return nullptr; } + bool GetOriginalUserGesture() override { return true; } + const GURL& GetURL() override { return url_; } + NavigateResult NavigateWithGesture( + const blink::mojom::WindowFeatures& window_features, + base::Optional<WindowOpenDisposition> updated_disposition) override { + return NavigateResult{nullptr, WindowOpenDisposition::UNKNOWN}; + } + void OnPopupBlocked(content::WebContents* web_contents, + int num_blocked) override {} - // ChromeRenderViewHostTestHarness: - void SetUp() override { - ChromeRenderViewHostTestHarness::SetUp(); + private: + const GURL url_; +}; - // Set up safe browsing service with the fake database manager. - // - // TODO(csharrison): This is a bit ugly. See if the instructions in - // test_safe_browsing_service.h can be adapted to be used in unit tests. - safe_browsing::TestSafeBrowsingServiceFactory sb_service_factory; - fake_safe_browsing_database_ = new FakeSafeBrowsingDatabaseManager(); - sb_service_factory.SetTestDatabaseManager( - fake_safe_browsing_database_.get()); - safe_browsing::SafeBrowsingService::RegisterFactory(&sb_service_factory); - auto* safe_browsing_service = - sb_service_factory.CreateSafeBrowsingService(); - safe_browsing::SafeBrowsingService::RegisterFactory(nullptr); - TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService( - safe_browsing_service); - g_browser_process->safe_browsing_service()->Initialize(); +// TODO(cduvall): Make a common test delegate to use here and other places that +// need it. +class TestTabSpecificContentSettingsDelegate + : public content_settings::TabSpecificContentSettings::Delegate { + public: + explicit TestTabSpecificContentSettingsDelegate( + HostContentSettingsMap* settings_map) + : settings_map_(settings_map) {} + void UpdateLocationBar() override {} + void SetContentSettingRules( + content::RenderProcessHost* process, + const RendererContentSettingRules& rules) override {} + PrefService* GetPrefs() override { return nullptr; } + HostContentSettingsMap* GetSettingsMap() override { return settings_map_; } + ContentSetting GetEmbargoSetting(const GURL& request_origin, + ContentSettingsType permission) override { + return ContentSetting::CONTENT_SETTING_ASK; + } + std::vector<storage::FileSystemType> GetAdditionalFileSystemTypes() override { + return {}; + } + browsing_data::CookieHelper::IsDeletionDisabledCallback + GetIsDeletionDisabledCallback() override { + return base::NullCallback(); + } + bool IsMicrophoneCameraStateChanged( + content_settings::TabSpecificContentSettings::MicrophoneCameraState + microphone_camera_state, + const std::string& media_stream_selected_audio_device, + const std::string& media_stream_selected_video_device) override { + return false; + } + content_settings::TabSpecificContentSettings::MicrophoneCameraState + GetMicrophoneCameraState() override { + return content_settings::TabSpecificContentSettings:: + MICROPHONE_CAMERA_NOT_ACCESSED; + } + void OnContentBlocked(ContentSettingsType type) override {} - // Required for the safe browsing notifications on navigation. - ChromeSubresourceFilterClient::CreateForWebContents(web_contents()); + private: + HostContentSettingsMap* settings_map_; +}; - scoped_feature_list_ = DefaultFeatureList(); - PopupBlockerTabHelper::CreateForWebContents(web_contents()); - InfoBarService::CreateForWebContents(web_contents()); - content_settings::TabSpecificContentSettings::CreateForWebContents( - web_contents(), - std::make_unique<chrome::TabSpecificContentSettingsDelegate>( - web_contents())); - popup_blocker_ = - blocked_content::SafeBrowsingTriggeredPopupBlocker::FromWebContents( - web_contents()); +class SafeBrowsingTriggeredPopupBlockerTest + : public content::RenderViewHostTestHarness, + public subresource_filter::SubresourceFilterClient { + public: + SafeBrowsingTriggeredPopupBlockerTest() = default; + ~SafeBrowsingTriggeredPopupBlockerTest() override { + settings_map_->ShutdownOnUIThread(); } - void TearDown() override { - fake_safe_browsing_database_ = nullptr; - TestingBrowserProcess::GetGlobal()->safe_browsing_service()->ShutDown(); + // subresource_filter::SubresourceFilterClient: + void ShowNotification() override {} + subresource_filter::mojom::ActivationLevel OnPageActivationComputed( + content::NavigationHandle* navigation_handle, + subresource_filter::mojom::ActivationLevel initial_activation_level, + subresource_filter::ActivationDecision* decision) override { + return initial_activation_level; + } - // Must explicitly set these to null and pump the run loop to ensure that - // all cleanup related to these classes actually happens. - TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(nullptr); - base::RunLoop().RunUntilIdle(); + // content::RenderViewHostTestHarness: + void SetUp() override { + content::RenderViewHostTestHarness::SetUp(); - ChromeRenderViewHostTestHarness::TearDown(); + fake_safe_browsing_database_ = + base::MakeRefCounted<FakeSafeBrowsingDatabaseManager>(); + + user_prefs::UserPrefs::Set(browser_context(), &pref_service_); + SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs( + pref_service_.registry()); + HostContentSettingsMap::RegisterProfilePrefs(pref_service_.registry()); + settings_map_ = base::MakeRefCounted<HostContentSettingsMap>( + &pref_service_, false, false, false, false); + + scoped_feature_list_ = DefaultFeatureList(); + subresource_filter::SubresourceFilterObserverManager::CreateForWebContents( + web_contents()); + PopupBlockerTabHelper::CreateForWebContents(web_contents()); + content_settings::TabSpecificContentSettings::CreateForWebContents( + web_contents(), + std::make_unique<TestTabSpecificContentSettingsDelegate>( + settings_map_.get())); + popup_blocker_ = + SafeBrowsingTriggeredPopupBlocker::FromWebContents(web_contents()); + + throttle_inserter_ = + std::make_unique<content::TestNavigationThrottleInserter>( + web_contents(), + base::BindRepeating( + &SafeBrowsingTriggeredPopupBlockerTest::CreateThrottle, + base::Unretained(this))); } virtual std::unique_ptr<base::test::ScopedFeatureList> DefaultFeatureList() { auto feature_list = std::make_unique<base::test::ScopedFeatureList>(); - feature_list->InitAndEnableFeature( - blocked_content::kAbusiveExperienceEnforce); + feature_list->InitAndEnableFeature(kAbusiveExperienceEnforce); return feature_list; } @@ -113,9 +172,7 @@ return scoped_feature_list_.get(); } - blocked_content::SafeBrowsingTriggeredPopupBlocker* popup_blocker() { - return popup_blocker_; - } + SafeBrowsingTriggeredPopupBlocker* popup_blocker() { return popup_blocker_; } void SimulateDeleteContents() { DeleteContents(); @@ -146,10 +203,23 @@ return rfh_tester->GetConsoleMessages(); } + HostContentSettingsMap* settings_map() { return settings_map_.get(); } + private: + std::unique_ptr<content::NavigationThrottle> CreateThrottle( + content::NavigationHandle* handle) { + return std::make_unique< + subresource_filter::SubresourceFilterSafeBrowsingActivationThrottle>( + handle, this, content::GetIOThreadTaskRunner({}), + fake_safe_browsing_database_); + } + std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_; scoped_refptr<FakeSafeBrowsingDatabaseManager> fake_safe_browsing_database_; - blocked_content::SafeBrowsingTriggeredPopupBlocker* popup_blocker_ = nullptr; + SafeBrowsingTriggeredPopupBlocker* popup_blocker_ = nullptr; + std::unique_ptr<content::TestNavigationThrottleInserter> throttle_inserter_; + sync_preferences::TestingPrefServiceSyncable pref_service_; + scoped_refptr<HostContentSettingsMap> settings_map_; DISALLOW_COPY_AND_ASSIGN(SafeBrowsingTriggeredPopupBlockerTest); }; @@ -195,8 +265,7 @@ EXPECT_TRUE(popup_blocker()->ShouldApplyAbusivePopupBlocker()); EXPECT_EQ(1u, GetMainFrameConsoleMessages().size()); - EXPECT_EQ(GetMainFrameConsoleMessages().front(), - blocked_content::kAbusiveEnforceMessage); + EXPECT_EQ(GetMainFrameConsoleMessages().front(), kAbusiveEnforceMessage); } TEST_F(SafeBrowsingTriggeredPopupBlockerTest, @@ -216,12 +285,9 @@ params.triggering_event_info = blink::TriggeringEventInfo::kFromUntrustedEvent; - NavigateParams nav_params(profile(), popup_url, ui::PAGE_TRANSITION_LINK); - nav_params.FillNavigateParamsFromOpenURLParams(params); - nav_params.source_contents = web_contents(); - nav_params.user_gesture = true; - MaybeBlockPopup(web_contents(), nullptr, &nav_params, ¶ms, - blink::mojom::WindowFeatures()); + MaybeBlockPopup(web_contents(), nullptr, + std::make_unique<TestPopupNavigationDelegate>(popup_url), + ¶ms, blink::mojom::WindowFeatures(), settings_map()); EXPECT_EQ(1u, PopupBlockerTabHelper::FromWebContents(web_contents()) ->GetBlockedPopupsCount()); @@ -243,12 +309,9 @@ params.user_gesture = true; params.triggering_event_info = blink::TriggeringEventInfo::kFromTrustedEvent; - NavigateParams nav_params(profile(), popup_url, ui::PAGE_TRANSITION_LINK); - nav_params.FillNavigateParamsFromOpenURLParams(params); - nav_params.source_contents = web_contents(); - nav_params.user_gesture = true; - MaybeBlockPopup(web_contents(), nullptr, &nav_params, ¶ms, - blink::mojom::WindowFeatures()); + MaybeBlockPopup(web_contents(), nullptr, + std::make_unique<TestPopupNavigationDelegate>(popup_url), + ¶ms, blink::mojom::WindowFeatures(), settings_map()); EXPECT_EQ(0u, PopupBlockerTabHelper::FromWebContents(web_contents()) ->GetBlockedPopupsCount()); @@ -263,11 +326,9 @@ TEST_F(SafeBrowsingTriggeredPopupBlockerTest, FeatureEnabledByDefault) { ResetFeatureAndGet(); - blocked_content::SafeBrowsingTriggeredPopupBlocker::MaybeCreate( - web_contents()); + SafeBrowsingTriggeredPopupBlocker::MaybeCreate(web_contents()); EXPECT_NE(nullptr, - blocked_content::SafeBrowsingTriggeredPopupBlocker::FromWebContents( - web_contents())); + SafeBrowsingTriggeredPopupBlocker::FromWebContents(web_contents())); } TEST_F(SafeBrowsingTriggeredPopupBlockerTest, OnlyBlockOnMatchingUrls) { @@ -331,13 +392,12 @@ int total_count = 0; // Call this when a new histogram entry is logged. Call it multiple times if // multiple entries are logged. - auto check_histogram = - [&](blocked_content::SafeBrowsingTriggeredPopupBlocker::Action action, - int expected_count) { - histogram_tester.ExpectBucketCount( - kActionHistogram, static_cast<int>(action), expected_count); - total_count++; - }; + auto check_histogram = [&](SafeBrowsingTriggeredPopupBlocker::Action action, + int expected_count) { + histogram_tester.ExpectBucketCount( + kActionHistogram, static_cast<int>(action), expected_count); + total_count++; + }; const GURL url_enforce("https://example.enforce/"); const GURL url_warn("https://example.warn/"); @@ -347,29 +407,19 @@ // Navigate to an enforce site. NavigateAndCommit(url_enforce); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, - 1); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kEnforcedSite, - 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kEnforcedSite, 1); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); // Block two popups. EXPECT_TRUE(popup_blocker()->ShouldApplyAbusivePopupBlocker()); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, - 1); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kBlocked, 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kBlocked, 1); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); EXPECT_TRUE(popup_blocker()->ShouldApplyAbusivePopupBlocker()); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, - 2); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kBlocked, 2); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 2); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kBlocked, 2); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); // Only log the num blocked histogram after navigation. @@ -379,33 +429,23 @@ NavigateAndCommit(url_warn); histogram_tester.ExpectBucketCount(kNumBlockedHistogram, 2, 1); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, - 2); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kWarningSite, - 1); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, 2); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kWarningSite, 1); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); // Let one popup through. EXPECT_FALSE(popup_blocker()->ShouldApplyAbusivePopupBlocker()); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, - 3); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 3); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); // Navigate to a site not matched in Safe Browsing. NavigateAndCommit(url_nothing); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, - 3); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kNavigation, 3); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); // Let one popup through. EXPECT_FALSE(popup_blocker()->ShouldApplyAbusivePopupBlocker()); - check_histogram( - blocked_content::SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, - 4); + check_histogram(SafeBrowsingTriggeredPopupBlocker::Action::kConsidered, 4); histogram_tester.ExpectTotalCount(kActionHistogram, total_count); histogram_tester.ExpectTotalCount(kNumBlockedHistogram, 1); @@ -437,8 +477,7 @@ // Warning should come at navigation commit time, not at popup time. EXPECT_EQ(1u, GetMainFrameConsoleMessages().size()); - EXPECT_EQ(GetMainFrameConsoleMessages().front(), - blocked_content::kAbusiveWarnMessage); + EXPECT_EQ(GetMainFrameConsoleMessages().front(), kAbusiveWarnMessage); EXPECT_FALSE(popup_blocker()->ShouldApplyAbusivePopupBlocker()); } @@ -455,8 +494,7 @@ // Warning should come at navigation commit time, not at popup time. EXPECT_EQ(2u, GetMainFrameConsoleMessages().size()); - EXPECT_EQ(GetMainFrameConsoleMessages().front(), - blocked_content::kAbusiveWarnMessage); + EXPECT_EQ(GetMainFrameConsoleMessages().front(), kAbusiveWarnMessage); EXPECT_EQ(GetMainFrameConsoleMessages().back(), subresource_filter::kActivationWarningConsoleMessage); @@ -516,3 +554,4 @@ } } } +} // namespace blocked_content
diff --git a/components/cast_channel/cast_message_handler.cc b/components/cast_channel/cast_message_handler.cc index 9609dcd..5bff7f1 100644 --- a/components/cast_channel/cast_message_handler.cc +++ b/components/cast_channel/cast_message_handler.cc
@@ -21,6 +21,9 @@ // The max launch timeout amount for session launch requests. constexpr base::TimeDelta kLaunchMaxTimeout = base::TimeDelta::FromMinutes(2); +// The max size of Cast Message is 64KB. +constexpr int kMaxCastMessagePayload = 64 * 1024; + void ReportParseError(const std::string& error) { DVLOG(1) << "Error parsing JSON message: " << error; } @@ -169,7 +172,7 @@ CreateReceiverStatusRequest(sender_id_, request_id)); } -void CastMessageHandler::SendBroadcastMessage( +Result CastMessageHandler::SendBroadcastMessage( int channel_id, const std::vector<std::string>& app_ids, const BroadcastRequest& request) { @@ -178,7 +181,7 @@ CastSocket* socket = socket_service_->GetSocket(channel_id); if (!socket) { DVLOG(2) << __func__ << ": socket not found: " << channel_id; - return; + return Result::kFailed; } int request_id = NextRequestId(); @@ -189,7 +192,11 @@ // about the response, as broadcasts are fire-and-forget. CastMessage message = CreateBroadcastRequest(sender_id_, request_id, app_ids, request); + if (message.ByteSizeLong() > kMaxCastMessagePayload) { + return Result::kFailed; + } SendCastMessageToSocket(socket, message); + return Result::kOk; } void CastMessageHandler::LaunchSession( @@ -213,12 +220,18 @@ launch_timeout = std::min(launch_timeout, kLaunchMaxTimeout); DVLOG(2) << __func__ << ", channel_id: " << channel_id << ", request_id: " << request_id; + CastMessage message = CreateLaunchRequest( + sender_id_, request_id, app_id, locale_, supported_app_types, app_params); + if (message.ByteSizeLong() > kMaxCastMessagePayload) { + LaunchSessionResponse response; + response.result = LaunchSessionResponse::kError; + std::move(callback).Run(std::move(response)); + return; + } if (requests->AddLaunchRequest(std::make_unique<LaunchSessionRequest>( request_id, std::move(callback), clock_), launch_timeout)) { - SendCastMessageToSocket( - socket, CreateLaunchRequest(sender_id_, request_id, app_id, locale_, - supported_app_types, app_params)); + SendCastMessageToSocket(socket, message); } } @@ -264,6 +277,9 @@ const CastMessage& message) { DCHECK(!IsCastInternalNamespace(message.namespace_())) << ": unexpected app message namespace: " << message.namespace_(); + if (message.ByteSizeLong() > kMaxCastMessagePayload) { + return Result::kFailed; + } return SendCastMessage(channel_id, message); }
diff --git a/components/cast_channel/cast_message_handler.h b/components/cast_channel/cast_message_handler.h index 4ba2066..32d1bef 100644 --- a/components/cast_channel/cast_message_handler.h +++ b/components/cast_channel/cast_message_handler.h
@@ -173,9 +173,9 @@ // Sends a broadcast message containing |app_ids| and |request| to the socket // given by |channel_id|. - virtual void SendBroadcastMessage(int channel_id, - const std::vector<std::string>& app_ids, - const BroadcastRequest& request); + virtual Result SendBroadcastMessage(int channel_id, + const std::vector<std::string>& app_ids, + const BroadcastRequest& request); // Requests a session launch for |app_id| on the device given by |channel_id|. // |callback| will be invoked with the response or with a timed out result if
diff --git a/components/cast_channel/cast_message_handler_unittest.cc b/components/cast_channel/cast_message_handler_unittest.cc index ec17f50..567c6630 100644 --- a/components/cast_channel/cast_message_handler_unittest.cc +++ b/components/cast_channel/cast_message_handler_unittest.cc
@@ -33,6 +33,8 @@ namespace { +constexpr char kAppId1[] = "0F5096E8"; +constexpr char kAppId2[] = "85CDB22F"; constexpr char kTestUserAgentString[] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/66.0.3331.0 Safari/537.36"; @@ -43,11 +45,13 @@ "requiredFeatures" : ["STREAM_TRANSFER"], "launchCheckerParams" : { "credentialsData" : { - "credentialsType" : "mobile", "credentials" : "99843n2idsguyhga" + "credentialsType" : "mobile", + "credentials" : "99843n2idsguyhga" } } } )"; +constexpr int kMaxProtocolMessageSize = 64 * 1024; data_decoder::DataDecoder::ValueOrError ParseJsonLikeDataDecoder( base::StringPiece json) { @@ -145,11 +149,11 @@ void CreatePendingRequests() { EXPECT_CALL(*transport_, SendMessage(_, _)).Times(AnyNumber()); - handler_.LaunchSession(channel_id_, "theAppId", base::TimeDelta::Max(), + handler_.LaunchSession(channel_id_, kAppId1, base::TimeDelta::Max(), {"WEB"}, /* appParams */ base::nullopt, launch_session_callback_.Get()); for (int i = 0; i < 2; i++) { - handler_.RequestAppAvailability(&cast_socket_, "theAppId", + handler_.RequestAppAvailability(&cast_socket_, kAppId1, get_app_availability_callback_.Get()); handler_.SendSetVolumeRequest( channel_id_, @@ -184,11 +188,11 @@ ExpectEnsureConnectionThen(CastMessageType::kGetAppAvailability, 2); handler_.RequestAppAvailability( - &cast_socket_, "AAAAAAAA", + &cast_socket_, kAppId1, base::BindOnce(&CastMessageHandlerTest::OnAppAvailability, base::Unretained(this))); handler_.RequestAppAvailability( - &cast_socket_, "BBBBBBBB", + &cast_socket_, kAppId2, base::BindOnce(&CastMessageHandlerTest::OnAppAvailability, base::Unretained(this))); } @@ -197,25 +201,25 @@ ExpectEnsureConnectionThen(CastMessageType::kGetAppAvailability); handler_.RequestAppAvailability( - &cast_socket_, "AAAAAAAA", + &cast_socket_, kAppId1, base::BindOnce(&CastMessageHandlerTest::OnAppAvailability, base::Unretained(this))); - EXPECT_CALL(*this, DoOnAppAvailability("AAAAAAAA", - GetAppAvailabilityResult::kUnknown)); + EXPECT_CALL(*this, + DoOnAppAvailability(kAppId1, GetAppAvailabilityResult::kUnknown)); OnError(ChannelError::TRANSPORT_ERROR); ExpectEnsureConnectionThen(CastMessageType::kGetAppAvailability); handler_.RequestAppAvailability( - &cast_socket_, "BBBBBBBB", + &cast_socket_, kAppId2, base::BindOnce(&CastMessageHandlerTest::OnAppAvailability, base::Unretained(this))); // The callback is invoked with kUnknown before the PendingRequests is // destroyed. - EXPECT_CALL(*this, DoOnAppAvailability("BBBBBBBB", - GetAppAvailabilityResult::kUnknown)); + EXPECT_CALL(*this, + DoOnAppAvailability(kAppId2, GetAppAvailabilityResult::kUnknown)); } TEST_F(CastMessageHandlerTest, RequestAppAvailability) { @@ -330,7 +334,7 @@ const base::Optional<base::Value> json = base::JSONReader().Read(kAppParams); handler_.LaunchSession( - channel_id_, "AAAAAAAA", base::TimeDelta::FromSeconds(30), {"WEB"}, json, + channel_id_, kAppId1, base::TimeDelta::FromSeconds(30), {"WEB"}, json, base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult, base::Unretained(this), LaunchSessionResponse::Result::kOk)); @@ -371,7 +375,7 @@ ExpectEnsureConnectionThen(CastMessageType::kLaunch); handler_.LaunchSession( - channel_id_, "AAAAAAAA", base::TimeDelta::FromSeconds(30), {"WEB"}, + channel_id_, kAppId1, base::TimeDelta::FromSeconds(30), {"WEB"}, /* appParams */ base::nullopt, base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult, base::Unretained(this), @@ -381,6 +385,19 @@ EXPECT_EQ(1, session_launch_response_count_); } +TEST_F(CastMessageHandlerTest, LaunchSessionMessageExceedsSizeLimit) { + std::string invalid_URL(kMaxProtocolMessageSize, 'a'); + base::Value json(base::Value::Type::DICTIONARY); + json.SetKey("key", base::Value(invalid_URL)); + handler_.LaunchSession( + channel_id_, kAppId1, base::TimeDelta::FromSeconds(30), {"WEB"}, + base::make_optional<base::Value>(std::move(json)), + base::BindOnce(&CastMessageHandlerTest::ExpectSessionLaunchResult, + base::Unretained(this), + LaunchSessionResponse::Result::kError)); + EXPECT_EQ(1, session_launch_response_count_); +} + TEST_F(CastMessageHandlerTest, SendAppMessage) { base::Value body(base::Value::Type::DICTIONARY); body.SetKey("foo", base::Value("bar")); @@ -396,6 +413,16 @@ EXPECT_EQ(Result::kOk, handler_.SendAppMessage(channel_id_, message)); } +TEST_F(CastMessageHandlerTest, SendAppMessageExceedsSizeLimit) { + std::string invalid_msg(kMaxProtocolMessageSize, 'a'); + base::Value body(base::Value::Type::DICTIONARY); + body.SetKey("foo", base::Value(invalid_msg)); + CastMessage message = + CreateCastMessage("namespace", body, kSourceId, kDestinationId); + + EXPECT_EQ(Result::kFailed, handler_.SendAppMessage(channel_id_, message)); +} + // Check that SendMediaRequest sends a message created by CreateMediaRequest and // returns a request ID. TEST_F(CastMessageHandlerTest, SendMediaRequest) { @@ -429,6 +456,31 @@ EXPECT_EQ(1, request_id); } +TEST_F(CastMessageHandlerTest, SendBroadcastMessage) { + BroadcastRequest request = BroadcastRequest("namespace", "message"); + CastMessage message = CreateBroadcastRequest( + "theSourceId", /* request_id */ 1, {kAppId1}, request); + { + InSequence dummy; + ExpectEnsureConnection(); + EXPECT_CALL(*transport_, + SendMessage(HasPayloadUtf8(message.payload_utf8()), _)); + } + + EXPECT_EQ(Result::kOk, + handler_.SendBroadcastMessage(channel_id_, {kAppId1}, request)); +} + +TEST_F(CastMessageHandlerTest, SendBroadcastMessageExceedsSizeLimit) { + BroadcastRequest request = + BroadcastRequest("namespace", std::string(kMaxProtocolMessageSize, 'a')); + CastMessage message = CreateBroadcastRequest( + "theSourceId", /* request_id */ 1, {kAppId1}, request); + + EXPECT_EQ(Result::kFailed, + handler_.SendBroadcastMessage(channel_id_, {kAppId1}, request)); +} + // Check that SendVolumeCommand sends a message created by CreateVolumeRequest // and registers a pending request. TEST_F(CastMessageHandlerTest, SendVolumeCommand) { @@ -474,7 +526,7 @@ EXPECT_EQ(base::nullopt, response.receiver_status); }); EXPECT_CALL(get_app_availability_callback_, - Run("theAppId", GetAppAvailabilityResult::kUnknown)) + Run(kAppId1, GetAppAvailabilityResult::kUnknown)) .Times(2); EXPECT_CALL(set_volume_callback_, Run(Result::kFailed)).Times(2); EXPECT_CALL(stop_session_callback_, Run(Result::kFailed)); @@ -496,7 +548,7 @@ testing::Optional(IsJson(R"({"foo": "bar"})"))); }); EXPECT_CALL(get_app_availability_callback_, - Run("theAppId", GetAppAvailabilityResult::kAvailable)) + Run(kAppId1, GetAppAvailabilityResult::kAvailable)) .Times(2); EXPECT_CALL(set_volume_callback_, Run(Result::kOk)).Times(2); EXPECT_CALL(stop_session_callback_, Run(Result::kOk)); @@ -512,13 +564,14 @@ })")); // Handle both pending get app availability requests. - handler_.HandleCastInternalMessage(channel_id_, "theSourceId", - "theDestinationId", "theNamespace", - ParseJsonLikeDataDecoder(R"( + handler_.HandleCastInternalMessage( + channel_id_, "theSourceId", "theDestinationId", "theNamespace", + ParseJsonLikeDataDecoder(base::StringPrintf(R"( { "requestId": 2, - "availability": {"theAppId": "APP_AVAILABLE"}, - })")); + "availability": {"%s": "APP_AVAILABLE"}, + })", + kAppId1))); // Handle pending set volume request (1 of 2). handler_.HandleCastInternalMessage(
diff --git a/components/cast_channel/cast_test_util.h b/components/cast_channel/cast_test_util.h index aa707c1..709c3e5 100644 --- a/components/cast_channel/cast_test_util.h +++ b/components/cast_channel/cast_test_util.h
@@ -175,9 +175,9 @@ GetAppAvailabilityCallback callback)); MOCK_METHOD1(RequestReceiverStatus, void(int channel_id)); MOCK_METHOD3(SendBroadcastMessage, - void(int, - const std::vector<std::string>&, - const BroadcastRequest&)); + Result(int, + const std::vector<std::string>&, + const BroadcastRequest&)); MOCK_METHOD6(LaunchSession, void(int, const std::string&,
diff --git a/components/cronet/stale_host_resolver.cc b/components/cronet/stale_host_resolver.cc index f5defe95..d87f852 100644 --- a/components/cronet/stale_host_resolver.cc +++ b/components/cronet/stale_host_resolver.cc
@@ -11,7 +11,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/check_op.h" -#include "base/metrics/histogram_macros.h" #include "base/notreached.h" #include "base/stl_util.h" #include "base/timer/timer.h" @@ -27,65 +26,6 @@ namespace cronet { -namespace { - -// Used in histograms; do not modify existing values. -enum RequestOutcome { - // Served from (valid) cache, hosts file, IP literal, etc. - SYNCHRONOUS = 0, - - // Network responded; there was no usable stale data. - NETWORK_WITHOUT_STALE = 1, - - // Network responded before stale delay; there was usable stale data. - NETWORK_WITH_STALE = 2, - - // Stale data returned; network didn't respond before the stale delay. - STALE_BEFORE_NETWORK = 3, - - // Request canceled; there was no usable stale data. - CANCELED_WITHOUT_STALE = 4, - - // Request canceled; there was usable stale data. - CANCELED_WITH_STALE = 5, - - // Stale data returned; network got ERR_NAME_NOT_RESOLVED. - STALE_INSTEAD_OF_NETWORK_NAME_NOT_RESOLVED = 6, - - // Stale data is explicitly requested and returned immediately. - STALE_SYNCHRONOUS = 7, - - MAX_REQUEST_OUTCOME -}; - -void RecordRequestOutcome(RequestOutcome outcome) { - UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolver.RequestOutcome", outcome, - MAX_REQUEST_OUTCOME); -} - -void RecordCacheSizes(size_t restored, size_t current) { - UMA_HISTOGRAM_COUNTS_1000("DNS.StaleHostResolver.RestoreSizeOnCacheMiss", - restored); - UMA_HISTOGRAM_COUNTS_1000("DNS.StaleHostResolver.SizeOnCacheMiss", current); -} - -void RecordAddressListDelta(net::AddressListDeltaType delta) { - UMA_HISTOGRAM_ENUMERATION("DNS.StaleHostResolver.StaleAddressListDelta", - delta, net::MAX_DELTA_TYPE); -} - -void RecordTimeDelta(base::TimeTicks network_time, base::TimeTicks stale_time) { - if (network_time <= stale_time) { - UMA_HISTOGRAM_LONG_TIMES_100("DNS.StaleHostResolver.NetworkEarly", - stale_time - network_time); - } else { - UMA_HISTOGRAM_LONG_TIMES_100("DNS.StaleHostResolver.NetworkLate", - network_time - stale_time); - } -} - -} // namespace - // A request made by the StaleHostResolver. May return fresh cached data, // network data, or stale cached data. class StaleHostResolver::RequestImpl @@ -98,7 +38,7 @@ const net::NetLogWithSource& net_log, const ResolveHostParameters& input_parameters, const base::TickClock* tick_clock); - ~RequestImpl() override; + ~RequestImpl() override = default; // net::HostResolver::ResolveHostRequest implementation: int Start(net::CompletionOnceCallback result_callback) override; @@ -131,20 +71,6 @@ // Callback for |stale_timer_| that returns stale results. void OnStaleDelayElapsed(); - // Logging for when the underlying resolve completes synchronously. - void RecordSynchronousRequest(); - // Logging for when the overall result is determined on completion of - // |network_request_|. - void RecordNetworkRequest( - int error, - bool returned_stale_data_instead_of_network_name_not_resolved); - // Logging for when |stale_timer_| fires and |stale_request_| is to be used as - // the overall result. - void RecordLateRequest(); - // Logging for when the request is cancelled after Start() is called and - // before a result is returned. - void RecordCanceledRequest(); - base::WeakPtr<StaleHostResolver> resolver_; const net::HostPortPair host_; @@ -169,13 +95,6 @@ // the overall result. std::unique_ptr<ResolveHostRequest> network_request_; - // Statistics used in histograms: - // Number of HostCache entries that were restored from prefs, recorded at the - // time the cache was checked. - size_t restore_size_; - // Current HostCache size at the time the cache was checked. - size_t current_size_; - base::WeakPtrFactory<RequestImpl> weak_ptr_factory_{this}; }; @@ -192,25 +111,15 @@ net_log_(net_log), input_parameters_(input_parameters), cache_error_(net::ERR_DNS_CACHE_MISS), - stale_timer_(tick_clock), - restore_size_(0), - current_size_(0) { + stale_timer_(tick_clock) { DCHECK(resolver_); } -StaleHostResolver::RequestImpl::~RequestImpl() { - if (!have_returned()) - RecordCanceledRequest(); -} - int StaleHostResolver::RequestImpl::Start( net::CompletionOnceCallback result_callback) { DCHECK(resolver_); DCHECK(!result_callback.is_null()); - restore_size_ = resolver_->inner_resolver_->LastRestoredCacheSize(); - current_size_ = resolver_->inner_resolver_->CacheSize(); - net::HostResolver::ResolveHostParameters cache_parameters = input_parameters_; cache_parameters.cache_usage = net::HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED; @@ -226,14 +135,12 @@ if (cache_error_ != net::ERR_DNS_CACHE_MISS && (!cache_request_->GetStaleInfo() || !cache_request_->GetStaleInfo().value().is_stale())) { - RecordSynchronousRequest(); return cache_error_; } if (cache_error_ != net::ERR_DNS_CACHE_MISS && input_parameters_.cache_usage == net::HostResolver::ResolveHostParameters::CacheUsage::STALE_ALLOWED) { - RecordRequestOutcome(STALE_SYNCHRONOUS); return cache_error_; } @@ -266,7 +173,6 @@ // /etc/hosts). if (network_rv != net::ERR_IO_PENDING) { stale_timer_.Stop(); - RecordSynchronousRequest(); } return network_rv; } @@ -343,9 +249,6 @@ resolver_->options_.use_stale_on_name_not_resolved && error == net::ERR_NAME_NOT_RESOLVED && have_cache_data(); - RecordNetworkRequest(error, - return_stale_data_instead_of_network_name_not_resolved); - stale_timer_.Stop(); if (return_stale_data_instead_of_network_name_not_resolved) { @@ -401,59 +304,9 @@ // even if |this| is destroyed. resolver_->DetachRequest(std::move(network_request_)); - RecordLateRequest(); std::move(result_callback_).Run(cache_error_); } -void StaleHostResolver::RequestImpl::RecordSynchronousRequest() { - RecordRequestOutcome(SYNCHRONOUS); -} - -void StaleHostResolver::RequestImpl::RecordNetworkRequest( - int error, - bool returned_stale_data_instead_of_network_name_not_resolved) { - DCHECK(resolver_); - - if (have_cache_data()) { - RecordTimeDelta(resolver_->tick_clock_->NowTicks(), - stale_timer_.desired_run_time()); - - if (cache_request_->GetAddressResults() && error == net::OK && - network_request_->GetAddressResults()) { - RecordAddressListDelta(FindAddressListDeltaType( - cache_request_->GetAddressResults().value(), - network_request_->GetAddressResults().value())); - } - - if (returned_stale_data_instead_of_network_name_not_resolved) { - RecordRequestOutcome(STALE_INSTEAD_OF_NETWORK_NAME_NOT_RESOLVED); - } else { - RecordRequestOutcome(NETWORK_WITH_STALE); - RecordCacheSizes(restore_size_, current_size_); - } - } else { - RecordRequestOutcome(NETWORK_WITHOUT_STALE); - } -} - -void StaleHostResolver::RequestImpl::RecordLateRequest() { - DCHECK(resolver_); - DCHECK(have_cache_data()); - - RecordTimeDelta(resolver_->tick_clock_->NowTicks(), - stale_timer_.desired_run_time()); - RecordRequestOutcome(STALE_BEFORE_NETWORK); -} - -void StaleHostResolver::RequestImpl::RecordCanceledRequest() { - DCHECK(!have_returned()); - - if (have_cache_data()) - RecordRequestOutcome(CANCELED_WITH_STALE); - else - RecordRequestOutcome(CANCELED_WITHOUT_STALE); -} - StaleHostResolver::StaleOptions::StaleOptions() : allow_other_network(false), max_stale_uses(0),
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index ed4ecd78..96040ec 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -238,6 +238,7 @@ "data_offer_unittest.cc", "data_source_unittest.cc", "display_unittest.cc", + "drag_drop_operation_unittest.cc", "gaming_seat_unittest.cc", "input_method_surface_unittest.cc", "keyboard_unittest.cc",
diff --git a/components/exo/drag_drop_operation.cc b/components/exo/drag_drop_operation.cc index 280be142..41e784b 100644 --- a/components/exo/drag_drop_operation.cc +++ b/components/exo/drag_drop_operation.cc
@@ -238,6 +238,8 @@ uint32_t dnd_operations = DndActionsToDragOperations(source_->get()->GetActions()); + base::WeakPtr<DragDropOperation> weak_ptr = weak_ptr_factory_.GetWeakPtr(); + started_by_this_object_ = true; // This triggers a nested run loop that terminates when the drag and drop // operation is completed. @@ -246,6 +248,10 @@ origin_->get()->window(), drag_start_point_, dnd_operations, event_source_); + // The instance deleted during StartDragAndDrop's nested RunLoop. + if (!weak_ptr) + return; + if (op) { // Success
diff --git a/components/exo/drag_drop_operation_unittest.cc b/components/exo/drag_drop_operation_unittest.cc new file mode 100644 index 0000000..9e02d45 --- /dev/null +++ b/components/exo/drag_drop_operation_unittest.cc
@@ -0,0 +1,127 @@ +// Copyright 2020 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/exo/drag_drop_operation.h" + +#include <memory> + +#include "ash/shell.h" +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/run_loop.h" +#include "components/exo/buffer.h" +#include "components/exo/data_source.h" +#include "components/exo/data_source_delegate.h" +#include "components/exo/surface.h" +#include "components/exo/test/exo_test_base.h" +#include "ui/aura/client/drag_drop_client.h" + +namespace exo { +namespace { + +constexpr char kText[] = "test"; +constexpr char kTextMimeType[] = "text/plain"; + +} // namespace + +class TestDataSourceDelegate : public DataSourceDelegate { + public: + // DataSourceDelegate: + void OnDataSourceDestroying(DataSource* source) override {} + + void OnTarget(const base::Optional<std::string>& mime_type) override {} + + void OnSend(const std::string& mime_type, base::ScopedFD fd) override { + base::WriteFileDescriptor(fd.get(), kText, sizeof(kText)); + } + + void OnCancelled() override {} + + void OnDndDropPerformed() override {} + + void OnDndFinished() override {} + + void OnAction(DndAction dnd_action) override {} + + bool CanAcceptDataEventsForSurface(Surface* surface) const override { + return true; + } +}; + +class DragDropOperationTest : public test::ExoTestBase, + public aura::client::DragDropClientObserver { + public: + DragDropOperationTest() = default; + ~DragDropOperationTest() override = default; + DragDropOperationTest(const DragDropOperationTest&) = delete; + DragDropOperationTest& operator=(const DragDropOperationTest&) = delete; + + void SetUp() override { + test::ExoTestBase::SetUp(); + aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()) + ->AddObserver(this); + } + + void TearDown() override { + aura::client::GetDragDropClient(ash::Shell::GetPrimaryRootWindow()) + ->RemoveObserver(this); + test::ExoTestBase::TearDown(); + } + + // aura::client::DragDropClientObserver: + void OnDragStarted() override { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, std::move(drag_blocked_callback_)); + } + + void OnDragEnded() override {} + + protected: + void set_drag_blocked_callback(base::OnceClosure callback) { + drag_blocked_callback_ = std::move(callback); + } + + private: + // Callback running inside the nested RunLoop in StartDragAndDrop(). + base::OnceClosure drag_blocked_callback_; +}; + +TEST_F(DragDropOperationTest, DeleteDuringDragging) { + auto delegate = std::make_unique<TestDataSourceDelegate>(); + auto data_source = std::make_unique<DataSource>(delegate.get()); + data_source->Offer(kTextMimeType); + + auto origin_surface = std::make_unique<Surface>(); + ash::Shell::GetPrimaryRootWindow()->AddChild(origin_surface->window()); + + gfx::Size buffer_size(100, 100); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + auto icon_surface = std::make_unique<Surface>(); + icon_surface->Attach(buffer.get()); + + auto operation = DragDropOperation::Create( + data_source.get(), origin_surface.get(), icon_surface.get(), gfx::Point(), + ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE); + icon_surface->Commit(); + + base::RunLoop run_loop; + set_drag_blocked_callback(base::BindOnce( + [](std::unique_ptr<DataSource> data_source, + base::WeakPtr<DragDropOperation> operation, + base::OnceClosure quit_closure) { + // This function runs inside the nested RunLoop in + // ash::DragDropController::StartDragAndDrop(). + EXPECT_TRUE(operation); + // Deleting DataSource causes DragDropOperation to be deleted as well. + data_source.reset(); + EXPECT_FALSE(operation); + std::move(quit_closure).Run(); + }, + std::move(data_source), operation, run_loop.QuitClosure())); + run_loop.Run(); + EXPECT_FALSE(operation); +} + +} // namespace exo
diff --git a/components/feed/core/v2/metrics_reporter.cc b/components/feed/core/v2/metrics_reporter.cc index 39a363b..b718bd43 100644 --- a/components/feed/core/v2/metrics_reporter.cc +++ b/components/feed/core/v2/metrics_reporter.cc
@@ -346,8 +346,8 @@ void MetricsReporter::OnLoadStream(LoadStreamStatus load_from_store_status, LoadStreamStatus final_status) { - LOG(ERROR) << "OnLoadStream load_from_store_status=" << load_from_store_status - << " final_status=" << final_status; + DVLOG(1) << "OnLoadStream load_from_store_status=" << load_from_store_status + << " final_status=" << final_status; base::UmaHistogramEnumeration( "ContentSuggestions.Feed.LoadStreamStatus.Initial", final_status); if (load_from_store_status != LoadStreamStatus::kNoStatus) { @@ -375,7 +375,7 @@ } void MetricsReporter::OnLoadMore(LoadStreamStatus status) { - LOG(ERROR) << "OnLoadMore status=" << status; + DVLOG(1) << "OnLoadMore status=" << status; base::UmaHistogramEnumeration( "ContentSuggestions.Feed.LoadStreamStatus.LoadMore", status); }
diff --git a/components/lookalikes/core/BUILD.gn b/components/lookalikes/core/BUILD.gn index ac6a4d28..65e89c84 100644 --- a/components/lookalikes/core/BUILD.gn +++ b/components/lookalikes/core/BUILD.gn
@@ -27,6 +27,7 @@ deps = [ ":core", + ":features", "//net:test_support", "//testing/gtest", ]
diff --git a/components/lookalikes/core/lookalike_url_util.cc b/components/lookalikes/core/lookalike_url_util.cc index 7900cf2..cc0c921 100644 --- a/components/lookalikes/core/lookalike_url_util.cc +++ b/components/lookalikes/core/lookalike_url_util.cc
@@ -48,6 +48,12 @@ // Tip. const size_t kMinWrongTLDLengthForInterstitial = 3; +// If enabled, detect target embeddings across TLDs, eg. detect google.gov-X.tld +// as a google.com embedding. This is tuned by further parameters below. +const base::FeatureParam<bool> kEnableTargetEmbeddingEnhancedProtection{ + &lookalikes::features::kDetectTargetEmbeddingLookalikes, + "enhanced_protection_enabled", false}; + // Domains using one of these TLDs will receive an extra layer of protection. // Even if the embedding target uses another valid TLD instead of their actual // TLD to embed them, the heuristic will trigger (for example @@ -354,16 +360,17 @@ std::vector<std::string> tlds_representing_words_list = base::SplitString(kTargetEmbeddingTldsRepresentingWords.Get(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - // If the |TLD| is one of the TLDs that is also a common English word, we only - // want to match with the actual TLD and not all important TLDs. - // For example, for youtube-to-mp4.com, there will be a call to this function - // with |e2LD| = "youtube" and |TLD| = "to". If "to" is in - // |tlds_representing_words_list|, we will only try to match "youtube.to". - // However, if "to" is not in |tlds_representing_words_list|, in addition to - // "youtube.to", we will try to test if "youtube" paired with any of - // |important_tlds| is an engaged or top 500 domain. + + // Enhanced Protection (aka Other-TLD) matching: + // + // When enabled, if |TLD| isn't a common English word, identify target + // embeddings wherein |TLD| is different than the protected domain's TLD. + // + // For example, when enabled, flag "youtube-net.*" as embedding, since + // youtube.com is a top domain (but don't trigger on youtube-to-*). DCHECK(!kTargetEmbeddingEnhancedProtectionTlds.Get().empty()); - if (!base::Contains(tlds_representing_words_list, TLD)) { + if (kEnableTargetEmbeddingEnhancedProtection.Get() && + !base::Contains(tlds_representing_words_list, TLD)) { important_tlds = base::SplitString(kTargetEmbeddingEnhancedProtectionTlds.Get(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
diff --git a/components/lookalikes/core/lookalike_url_util_unittest.cc b/components/lookalikes/core/lookalike_url_util_unittest.cc index 5530be9..97a4dc2 100644 --- a/components/lookalikes/core/lookalike_url_util_unittest.cc +++ b/components/lookalikes/core/lookalike_url_util_unittest.cc
@@ -6,6 +6,8 @@ #include "base/bind.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "components/lookalikes/core/features.h" #include "testing/gtest/include/gtest/gtest.h" TEST(LookalikeUrlUtilTest, IsEditDistanceAtMostOne) { @@ -71,15 +73,45 @@ return hostname.host() == "scholar.google.com"; } +struct TargetEmbeddingHeuristicTestCase { + const std::string hostname; + // Empty when there is no match. + const std::string expected_safe_host; + const TargetEmbeddingType expected_type; +}; + +void ValidateTestCases( + const std::vector<DomainInfo>& engaged_sites, + const std::vector<TargetEmbeddingHeuristicTestCase>& test_cases) { + for (auto& test_case : test_cases) { + std::string safe_hostname; + TargetEmbeddingType embedding_type = GetTargetEmbeddingType( + test_case.hostname, engaged_sites, + base::BindRepeating(&IsGoogleScholar), &safe_hostname); + if (test_case.expected_type != TargetEmbeddingType::kNone) { + EXPECT_EQ(safe_hostname, test_case.expected_safe_host) + << "Expected that \"" << test_case.hostname + << " should trigger because of " << test_case.expected_safe_host + << " But " + << (safe_hostname.empty() ? "it didn't trigger." + : "triggered because of ") + << safe_hostname; + EXPECT_EQ(embedding_type, test_case.expected_type) + << "Right warning type was not triggered for " << test_case.hostname + << "."; + } else { + EXPECT_EQ(embedding_type, TargetEmbeddingType::kNone) + << "Expected that " << test_case.hostname + << "\" shouldn't trigger but it did. Because of URL:" + << safe_hostname; + } + } +} + TEST(LookalikeUrlUtilTest, TargetEmbeddingTest) { - const std::vector<DomainInfo> engaged_sites = { + const std::vector<DomainInfo> kEngagedSites = { GetDomainInfo(GURL("https://highengagement.com"))}; - const struct TargetEmbeddingHeuristicTestCase { - const std::string hostname; - // Empty when there is no match. - const std::string safe_hostname; - const TargetEmbeddingType embedding_type; - } kTestCases[] = { + const std::vector<TargetEmbeddingHeuristicTestCase> kTestCases = { // The length of the url should not affect the outcome. {"this-is-a-very-long-url-but-it-should-not-affect-the-" "outcome-of-this-target-embedding-test-google.com-login.com", @@ -159,7 +191,10 @@ {"google.com", "", TargetEmbeddingType::kNone}, {"google.co.uk", "", TargetEmbeddingType::kNone}, {"google.randomreg-login.com", "", TargetEmbeddingType::kNone}, + }; + // Test cases for "enhanced protection", aka mixed-TLD, target embedding. + const std::vector<TargetEmbeddingHeuristicTestCase> kEPTestCases = { // Same tests with another important TLDs. {"this-is-a-very-long-url-but-it-should-not-affect-the-" "outcome-of-this-target-embedding-test-google.edu-login.com", @@ -224,26 +259,12 @@ {"foo.googleedu-foo.com", "", TargetEmbeddingType::kNone}, }; - for (const auto& kTestCase : kTestCases) { - std::string safe_hostname; - TargetEmbeddingType embedding_type = GetTargetEmbeddingType( - kTestCase.hostname, engaged_sites, - base::BindRepeating(&IsGoogleScholar), &safe_hostname); - if (kTestCase.embedding_type != TargetEmbeddingType::kNone) { - EXPECT_EQ(safe_hostname, kTestCase.safe_hostname) - << "Expected that \"" << kTestCase.hostname - << " should trigger because of " << kTestCase.safe_hostname << " But " - << (safe_hostname.empty() ? "it didn't trigger." - : "triggered because of ") - << safe_hostname; - EXPECT_EQ(embedding_type, kTestCase.embedding_type) - << "Right warning type was not triggered for " << kTestCase.hostname - << "."; - } else { - EXPECT_EQ(embedding_type, TargetEmbeddingType::kNone) - << "Expected that " << kTestCase.hostname - << "\" shouldn't trigger but it did. Because of URL:" - << safe_hostname; - } - } + ValidateTestCases(kEngagedSites, kTestCases); + + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeatureWithParameters( + lookalikes::features::kDetectTargetEmbeddingLookalikes, + {{"enhanced_protection_enabled", "true"}}); + + ValidateTestCases(kEngagedSites, kEPTestCases); }
diff --git a/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.cc index 1a67728a..7ba191b 100644 --- a/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.cc +++ b/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.cc
@@ -308,6 +308,14 @@ const char kHistogramNavigationTimingNavigationStartToFirstLoaderCallback[] = "PageLoad.Experimental.NavigationTiming." "NavigationStartToFirstLoaderCallback"; +const char kHistogramNavigationTimingNavigationStartToFinalRequestStart[] = + "PageLoad.Experimental.NavigationTiming.NavigationStartToFinalRequestStart"; +const char kHistogramNavigationTimingNavigationStartToFinalResponseStart[] = + "PageLoad.Experimental.NavigationTiming." + "NavigationStartToFinalResponseStart"; +const char kHistogramNavigationTimingNavigationStartToFinalLoaderCallback[] = + "PageLoad.Experimental.NavigationTiming." + "NavigationStartToFinalLoaderCallback"; const char kHistogramNavigationTimingNavigationStartToNavigationCommitSent[] = "PageLoad.Experimental.NavigationTiming." "NavigationStartToNavigationCommitSent"; @@ -319,6 +327,16 @@ const char kHistogramNavigationTimingFirstResponseStartToFirstLoaderCallback[] = "PageLoad.Experimental.NavigationTiming." "FirstResponseStartToFirstLoaderCallback"; +const char kHistogramNavigationTimingFinalRequestStartToFinalResponseStart[] = + "PageLoad.Experimental.NavigationTiming." + "FinalRequestStartToFinalResponseStart"; +const char kHistogramNavigationTimingFinalResponseStartToFinalLoaderCallback[] = + "PageLoad.Experimental.NavigationTiming." + "FinalResponseStartToFinalLoaderCallback"; +const char + kHistogramNavigationTimingFinalLoaderCallbackToNavigationCommitSent[] = + "PageLoad.Experimental.NavigationTiming." + "FinalLoaderCallbackToNavigationCommitSent"; } // namespace internal @@ -802,6 +820,9 @@ timing.first_request_start_time.is_null() || timing.first_response_start_time.is_null() || timing.first_loader_callback_time.is_null() || + timing.final_request_start_time.is_null() || + timing.final_response_start_time.is_null() || + timing.final_loader_callback_time.is_null() || timing.navigation_commit_sent_time.is_null()) return; // TODO(https://crbug.com/1076710): Change these early-returns to DCHECKs @@ -812,6 +833,16 @@ timing.first_loader_callback_time > timing.navigation_commit_sent_time) { return; } + if (navigation_start_time > timing.final_request_start_time || + timing.final_request_start_time > timing.final_response_start_time || + timing.final_response_start_time > timing.final_loader_callback_time || + timing.final_loader_callback_time > timing.navigation_commit_sent_time) { + return; + } + DCHECK_LE(timing.first_request_start_time, timing.final_request_start_time); + DCHECK_LE(timing.first_response_start_time, timing.final_response_start_time); + DCHECK_LE(timing.first_loader_callback_time, + timing.final_loader_callback_time); // Record the elapsed time from the navigation start milestone. PAGE_LOAD_HISTOGRAM( @@ -823,6 +854,17 @@ PAGE_LOAD_HISTOGRAM( internal::kHistogramNavigationTimingNavigationStartToFirstLoaderCallback, timing.first_loader_callback_time - navigation_start_time); + + PAGE_LOAD_HISTOGRAM( + internal::kHistogramNavigationTimingNavigationStartToFinalRequestStart, + timing.final_request_start_time - navigation_start_time); + PAGE_LOAD_HISTOGRAM( + internal::kHistogramNavigationTimingNavigationStartToFinalResponseStart, + timing.final_response_start_time - navigation_start_time); + PAGE_LOAD_HISTOGRAM( + internal::kHistogramNavigationTimingNavigationStartToFinalLoaderCallback, + timing.final_loader_callback_time - navigation_start_time); + PAGE_LOAD_HISTOGRAM( internal::kHistogramNavigationTimingNavigationStartToNavigationCommitSent, timing.navigation_commit_sent_time - navigation_start_time); @@ -835,6 +877,19 @@ internal:: kHistogramNavigationTimingFirstResponseStartToFirstLoaderCallback, timing.first_loader_callback_time - timing.first_response_start_time); + + PAGE_LOAD_HISTOGRAM( + internal::kHistogramNavigationTimingFinalRequestStartToFinalResponseStart, + timing.final_response_start_time - timing.final_request_start_time); + PAGE_LOAD_HISTOGRAM( + internal:: + kHistogramNavigationTimingFinalResponseStartToFinalLoaderCallback, + timing.final_loader_callback_time - timing.final_response_start_time); + + PAGE_LOAD_HISTOGRAM( + internal:: + kHistogramNavigationTimingFinalLoaderCallbackToNavigationCommitSent, + timing.navigation_commit_sent_time - timing.final_loader_callback_time); } // This method records values for metrics that were not recorded during any
diff --git a/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.h b/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.h index b5a15c7..d1b75deb 100644 --- a/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.h +++ b/components/page_load_metrics/browser/observers/core_page_load_metrics_observer.h
@@ -115,6 +115,12 @@ extern const char kHistogramNavigationTimingNavigationStartToFirstLoaderCallback[]; extern const char + kHistogramNavigationTimingNavigationStartToFinalRequestStart[]; +extern const char + kHistogramNavigationTimingNavigationStartToFinalResponseStart[]; +extern const char + kHistogramNavigationTimingNavigationStartToFinalLoaderCallback[]; +extern const char kHistogramNavigationTimingNavigationStartToNavigationCommitSent[]; // Navigation metrics between milestones. @@ -122,6 +128,12 @@ kHistogramNavigationTimingFirstRequestStartToFirstResponseStart[]; extern const char kHistogramNavigationTimingFirstResponseStartToFirstLoaderCallback[]; +extern const char + kHistogramNavigationTimingFinalRequestStartToFinalResponseStart[]; +extern const char + kHistogramNavigationTimingFinalResponseStartToFinalLoaderCallback[]; +extern const char + kHistogramNavigationTimingFinalLoaderCallbackToNavigationCommitSent[]; enum FirstMeaningfulPaintStatus { FIRST_MEANINGFUL_PAINT_RECORDED,
diff --git a/components/page_load_metrics/browser/observers/core_page_load_metrics_observer_unittest.cc b/components/page_load_metrics/browser/observers/core_page_load_metrics_observer_unittest.cc index 95d65ce..78bf96b 100644 --- a/components/page_load_metrics/browser/observers/core_page_load_metrics_observer_unittest.cc +++ b/components/page_load_metrics/browser/observers/core_page_load_metrics_observer_unittest.cc
@@ -515,6 +515,9 @@ internal::kHistogramNavigationTimingNavigationStartToFirstRequestStart, internal::kHistogramNavigationTimingNavigationStartToFirstResponseStart, internal::kHistogramNavigationTimingNavigationStartToFirstLoaderCallback, + internal::kHistogramNavigationTimingNavigationStartToFinalRequestStart, + internal::kHistogramNavigationTimingNavigationStartToFinalResponseStart, + internal::kHistogramNavigationTimingNavigationStartToFinalLoaderCallback, internal:: kHistogramNavigationTimingNavigationStartToNavigationCommitSent}; for (const char* metric : metrics_from_navigation_start) @@ -524,7 +527,12 @@ std::vector<const char*> metrics_between_milestones = { internal::kHistogramNavigationTimingFirstRequestStartToFirstResponseStart, internal:: - kHistogramNavigationTimingFirstResponseStartToFirstLoaderCallback}; + kHistogramNavigationTimingFirstResponseStartToFirstLoaderCallback, + internal::kHistogramNavigationTimingFinalRequestStartToFinalResponseStart, + internal:: + kHistogramNavigationTimingFinalResponseStartToFinalLoaderCallback, + internal:: + kHistogramNavigationTimingFinalLoaderCallbackToNavigationCommitSent}; for (const char* metric : metrics_between_milestones) tester()->histogram_tester().ExpectTotalCount(metric, 1); }
diff --git a/components/performance_manager/graph/frame_node_impl.cc b/components/performance_manager/graph/frame_node_impl.cc index 38f04fe9..eda0f75 100644 --- a/components/performance_manager/graph/frame_node_impl.cc +++ b/components/performance_manager/graph/frame_node_impl.cc
@@ -540,7 +540,7 @@ DCHECK(child_frame_nodes_.empty()); // Sever opener relationships. - SeverOpenedPagesAndMaybeReparentPopups(); + SeverOpenedPagesAndMaybeReparent(); // Leave the page. DCHECK(graph()->NodeInGraph(page_node_)); @@ -561,28 +561,31 @@ render_frame_id_, this); } -void FrameNodeImpl::SeverOpenedPagesAndMaybeReparentPopups() { +void FrameNodeImpl::SeverOpenedPagesAndMaybeReparent() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - using OpenedType = PageNode::OpenedType; - - // Copy |opened_page_nodes_| as we'll be modifying it in this loop. + // Copy |opened_page_nodes_| as we'll be modifying it in this loop: when we + // call PageNodeImpl::(Set|Clear)OpenerFrameNodeAndOpenedType() this will call + // back into this frame node and call RemoveOpenedPage(). base::flat_set<PageNodeImpl*> opened_nodes = opened_page_nodes_; for (auto* opened_node : opened_nodes) { - const bool is_popup = opened_node->opened_type() == OpenedType::kPopup; + auto opened_type = opened_node->opened_type(); - opened_node->ClearOpenerFrameNodeAndOpenedType(); - - // Special case: child popups are reparented to the root of the frame tree. - // See WebContentsImpl::SetOpenerForNewContents. - if (is_popup) { - auto* main_frame = GetFrameTreeRoot(); - if (main_frame != this) { - opened_node->SetOpenerFrameNodeAndOpenedType(main_frame, - OpenedType::kPopup); - } + // Reparent opened pages to this frame's parent to maintain the relationship + // between the frame trees for bookkeeping. For the relationship to be + // finally severed one of the frame trees must completely disappear, or it + // must be explicitly severed (this can happen with portals). + if (parent_frame_node_) { + opened_node->SetOpenerFrameNodeAndOpenedType(parent_frame_node_, + opened_type); + } else { + // There's no new parent, so simply clear the opener. + opened_node->ClearOpenerFrameNodeAndOpenedType(); } } + + // Expect each page node to have called RemoveOpenedPage(), and for this to + // now be empty. DCHECK(opened_page_nodes_.empty()); }
diff --git a/components/performance_manager/graph/frame_node_impl.h b/components/performance_manager/graph/frame_node_impl.h index b8eea011..314a04dd 100644 --- a/components/performance_manager/graph/frame_node_impl.h +++ b/components/performance_manager/graph/frame_node_impl.h
@@ -135,8 +135,8 @@ return weak_factory_.GetWeakPtr(); } - void SeverOpenedPagesAndMaybeReparentPopupsForTesting() { - SeverOpenedPagesAndMaybeReparentPopups(); + void SeverOpenedPagesAndMaybeReparentForTesting() { + SeverOpenedPagesAndMaybeReparent(); } protected: @@ -226,9 +226,9 @@ // Helper function to sever all opened page relationships. This is called // before destroying the frame node in "OnBeforeLeavingGraph". Note that this - // will reparent popups to the root frame of the page if this frame isn't - // the root. - void SeverOpenedPagesAndMaybeReparentPopups(); + // will reparent opened pages to this frame's parent so that tracking is + // maintained. + void SeverOpenedPagesAndMaybeReparent(); // This is not quite the same as GetMainFrame, because there can be multiple // main frames while the main frame is navigating. This explicitly walks up
diff --git a/components/performance_manager/graph/frame_node_impl_unittest.cc b/components/performance_manager/graph/frame_node_impl_unittest.cc index d7bd847..de89772 100644 --- a/components/performance_manager/graph/frame_node_impl_unittest.cc +++ b/components/performance_manager/graph/frame_node_impl_unittest.cc
@@ -498,7 +498,7 @@ // You can always call the pre-delete opener clearing helper, even if you // have no such relationships. - frameB1->SeverOpenedPagesAndMaybeReparentPopupsForTesting(); + frameB1->SeverOpenedPagesAndMaybeReparentForTesting(); // You can't clear an opener if you don't already have one. EXPECT_DCHECK_DEATH(pageB->ClearOpenerFrameNodeAndOpenedType()); @@ -534,11 +534,6 @@ EXPECT_EQ(1u, pframeA1->GetOpenedPageNodes().count(pageB.get())); testing::Mock::VerifyAndClear(&obs); - // Once you have an opener, you can't set it again (it has to be cleared - // first). - EXPECT_DCHECK_DEATH(pageB->SetOpenerFrameNodeAndOpenedType( - frameA1.get(), OpenedType::kPopup)); - // Set another opener relationship. EXPECT_CALL(obs, OnOpenerFrameNodeChanged(pageC.get(), nullptr, OpenedType::kInvalid)); @@ -589,7 +584,7 @@ // Clear the second relationship (initiated from the frame). EXPECT_CALL(obs, OnOpenerFrameNodeChanged(pageC.get(), frameA1.get(), OpenedType::kPopup)); - frameA1->SeverOpenedPagesAndMaybeReparentPopupsForTesting(); + frameA1->SeverOpenedPagesAndMaybeReparentForTesting(); EXPECT_EQ(nullptr, pageC->opener_frame_node()); EXPECT_EQ(OpenedType::kInvalid, pageC->opened_type()); EXPECT_TRUE(frameA1->opened_page_nodes().empty()); @@ -609,9 +604,7 @@ // Clear it with the helper, and expect it to be reparented to node A1. EXPECT_CALL(obs, OnOpenerFrameNodeChanged(pageB.get(), frameA2.get(), OpenedType::kPopup)); - EXPECT_CALL(obs, OnOpenerFrameNodeChanged(pageB.get(), nullptr, - OpenedType::kInvalid)); - frameA2->SeverOpenedPagesAndMaybeReparentPopupsForTesting(); + frameA2->SeverOpenedPagesAndMaybeReparentForTesting(); EXPECT_EQ(frameA1.get(), pageB->opener_frame_node()); EXPECT_EQ(OpenedType::kPopup, pageB->opened_type()); EXPECT_EQ(1u, frameA1->opened_page_nodes().size()); @@ -623,7 +616,7 @@ // was already parented to the root. EXPECT_CALL(obs, OnOpenerFrameNodeChanged(pageB.get(), frameA1.get(), OpenedType::kPopup)); - frameA1->SeverOpenedPagesAndMaybeReparentPopupsForTesting(); + frameA1->SeverOpenedPagesAndMaybeReparentForTesting(); EXPECT_EQ(nullptr, pageB->opener_frame_node()); EXPECT_EQ(OpenedType::kInvalid, pageB->opened_type()); EXPECT_TRUE(frameA1->opened_page_nodes().empty());
diff --git a/components/performance_manager/graph/page_node.cc b/components/performance_manager/graph/page_node.cc index 772581fa..113fcf4c 100644 --- a/components/performance_manager/graph/page_node.cc +++ b/components/performance_manager/graph/page_node.cc
@@ -8,6 +8,21 @@ namespace performance_manager { +// static +const char* PageNode::ToString(PageNode::OpenedType opened_type) { + switch (opened_type) { + case PageNode::OpenedType::kInvalid: + return "kInvalid"; + case PageNode::OpenedType::kPopup: + return "kPopup"; + case PageNode::OpenedType::kGuestView: + return "kGuestView"; + case PageNode::OpenedType::kPortal: + return "kPortal"; + } + NOTREACHED(); +} + PageNode::PageNode() = default; PageNode::~PageNode() = default; @@ -18,3 +33,10 @@ PageNode::ObserverDefaultImpl::~ObserverDefaultImpl() = default; } // namespace performance_manager + +std::ostream& operator<<( + std::ostream& os, + performance_manager::PageNode::OpenedType opened_type) { + os << performance_manager::PageNode::ToString(opened_type); + return os; +} \ No newline at end of file
diff --git a/components/performance_manager/graph/page_node_impl.cc b/components/performance_manager/graph/page_node_impl.cc index 50d2b709..14ec570a 100644 --- a/components/performance_manager/graph/page_node_impl.cc +++ b/components/performance_manager/graph/page_node_impl.cc
@@ -253,16 +253,17 @@ DCHECK_NE(this, opener->page_node()); DCHECK_NE(OpenedType::kInvalid, opened_type); - // Can't already have an opener. - DCHECK_EQ(nullptr, opener_frame_node_); - DCHECK_EQ(OpenedType::kInvalid, opened_type_); + auto* previous_opener = opener_frame_node_; + auto previous_type = opened_type_; + if (previous_opener) + previous_opener->RemoveOpenedPage(PassKey(), this); opener_frame_node_ = opener; opened_type_ = opened_type; opener->AddOpenedPage(PassKey(), this); for (auto* observer : GetObservers()) - observer->OnOpenerFrameNodeChanged(this, nullptr, OpenedType::kInvalid); + observer->OnOpenerFrameNodeChanged(this, previous_opener, previous_type); } void PageNodeImpl::ClearOpenerFrameNodeAndOpenedType() {
diff --git a/components/performance_manager/graph/page_node_impl_describer.cc b/components/performance_manager/graph/page_node_impl_describer.cc index 8b04bc7..6032b96 100644 --- a/components/performance_manager/graph/page_node_impl_describer.cc +++ b/components/performance_manager/graph/page_node_impl_describer.cc
@@ -76,6 +76,10 @@ page_node_impl->is_holding_indexeddb_lock_.value()); result.SetBoolKey("had_form_interaction", page_node_impl->had_form_interaction_.value()); + if (page_node_impl->opened_type_ != PageNode::OpenedType::kInvalid) { + result.SetStringKey("opened_type", + PageNode::ToString(page_node_impl->opened_type_)); + } return result; }
diff --git a/components/performance_manager/performance_manager_browsertest.cc b/components/performance_manager/performance_manager_browsertest.cc index 13f52478..721a436 100644 --- a/components/performance_manager/performance_manager_browsertest.cc +++ b/components/performance_manager/performance_manager_browsertest.cc
@@ -19,6 +19,7 @@ #include "content/public/test/browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gtest/include/gtest/gtest.h" namespace performance_manager { @@ -84,4 +85,35 @@ run_loop_after_contents_reset.Run(); } +IN_PROC_BROWSER_TEST_F(PerformanceManagerBrowserTest, + PopupOpenerTrackingWorks) { + // Load a page that will load a popup. + GURL url(embedded_test_server()->GetURL("a.com", "/a_popup_a.html")); + content::ShellAddedObserver shell_added_observer; + ASSERT_TRUE(NavigateToURL(shell(), url)); + + // Wait for the popup window to appear, and then wait for it to load. + auto* popup = shell_added_observer.GetShell(); + ASSERT_TRUE(popup); + NotifyShellCreated(popup); + WaitForLoad(popup->web_contents()); + + auto* contents = shell()->web_contents(); + auto page = PerformanceManager::GetPageNodeForWebContents(contents); + + // Jump into the graph and make sure everything is connected as expected. + base::RunLoop run_loop; + PerformanceManager::CallOnGraph( + FROM_HERE, base::BindLambdaForTesting([&page, &run_loop]() { + EXPECT_TRUE(page); + auto* frame = page->GetMainFrameNode(); + EXPECT_EQ(1u, frame->GetOpenedPageNodes().size()); + auto* opened_page = *(frame->GetOpenedPageNodes().begin()); + EXPECT_EQ(PageNode::OpenedType::kPopup, opened_page->GetOpenedType()); + EXPECT_EQ(frame, opened_page->GetOpenerFrameNode()); + run_loop.Quit(); + })); + run_loop.Run(); +} + } // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_tab_helper.cc b/components/performance_manager/performance_manager_tab_helper.cc index 4580b9d..6b783a5 100644 --- a/components/performance_manager/performance_manager_tab_helper.cc +++ b/components/performance_manager/performance_manager_tab_helper.cc
@@ -25,24 +25,73 @@ namespace performance_manager { +namespace { + +// Returns true if the opener relationship exists, false otherwise. +bool ConnectWindowOpenRelationshipIfExists(PerformanceManagerTabHelper* helper, + content::WebContents* web_contents) { + // Prefer to use GetOpener() if available, as it is more specific and points + // directly to the frame that actually called window.open. + auto* opener_rfh = web_contents->GetOpener(); + if (!opener_rfh) { + // If the child page is opened with "noopener" then the parent document + // maintains the ability to close the child, but the child can't reach back + // and see it's parent. In this case there will be no "Opener", but there + // will be an "OriginalOpener". + opener_rfh = web_contents->GetOriginalOpener(); + } + + if (!opener_rfh) + return false; + + // You can't simultaneously be a portal (an embedded child element of a + // document loaded via the <portal> tag) and a popup (a child document + // loaded in a new window). + DCHECK(!web_contents->IsPortal()); + + // Connect this new page to its opener. + auto* opener_wc = content::WebContents::FromRenderFrameHost(opener_rfh); + auto* opener_helper = PerformanceManagerTabHelper::FromWebContents(opener_wc); + DCHECK(opener_helper); // We should already have seen the opener WC. + + // On CrOS the opener can be the ChromeKeyboardWebContents, whose RFHs never + // make it to a "created" state, so the PM never learns about them. + // https://crbug.com/1090374 + auto* opener_frame_node = opener_helper->GetFrameNode(opener_rfh); + if (!opener_frame_node) + return false; + + PerformanceManagerImpl::CallOnGraphImpl( + FROM_HERE, base::BindOnce(&PageNodeImpl::SetOpenerFrameNodeAndOpenedType, + base::Unretained(helper->page_node()), + base::Unretained(opener_frame_node), + PageNode::OpenedType::kPopup)); + return true; +} + +} // namespace + PerformanceManagerTabHelper::PerformanceManagerTabHelper( content::WebContents* web_contents) : content::WebContentsObserver(web_contents) { + // Create the page node. page_node_ = PerformanceManagerImpl::CreatePageNode( WebContentsProxy(weak_factory_.GetWeakPtr()), web_contents->GetBrowserContext()->UniqueId(), web_contents->GetVisibleURL(), web_contents->GetVisibility() == content::Visibility::VISIBLE, web_contents->IsCurrentlyAudible(), web_contents->GetLastActiveTime()); - // Dispatch creation notifications for any pre-existing frames. - std::vector<content::RenderFrameHost*> existing_frames = - web_contents->GetAllFrames(); - for (content::RenderFrameHost* frame : existing_frames) { - // Only send notifications for created frames, the others will generate - // creation notifications in due course (or not at all). - if (frame->IsRenderFrameCreated()) - RenderFrameCreated(frame); - } + + // We have an early WebContents creation hook so should see it when there is + // only a single frame, and it is not yet created. We sanity check that here. +#if DCHECK_IS_ON() + DCHECK(!web_contents->GetMainFrame()->IsRenderFrameCreated()); + std::vector<content::RenderFrameHost*> frames = web_contents->GetAllFrames(); + DCHECK_EQ(1u, frames.size()); + DCHECK_EQ(web_contents->GetMainFrame(), frames[0]); +#endif + + ConnectWindowOpenRelationshipIfExists(this, web_contents); } PerformanceManagerTabHelper::~PerformanceManagerTabHelper() { @@ -309,6 +358,68 @@ base::Unretained(page_node_.get()))); } +void PerformanceManagerTabHelper::InnerWebContentsAttached( + content::WebContents* inner_web_contents, + content::RenderFrameHost* render_frame_host, + bool /* is_full_page */) { + // Note that we sometimes learn of contents creation at this point (before + // other helpers get a chance to attach), so we need to ensure our helper + // exists. + CreateForWebContents(inner_web_contents); + auto* helper = FromWebContents(inner_web_contents); + DCHECK(helper); + auto* page = helper->page_node_.get(); + DCHECK(page); + auto* frame = GetFrameNode(render_frame_host); + + // Determine the opened type. + auto opened_type = PageNode::OpenedType::kInvalid; + if (inner_web_contents->IsPortal()) { + // Portals don't have openers. + DCHECK(!inner_web_contents->HasOpener() && + !inner_web_contents->HasOriginalOpener()); + opened_type = PageNode::OpenedType::kPortal; + + // In the case of portals there can be a temporary RFH that is created that + // will never actually be committed to the frame tree (for which we'll never + // see RenderFrameCreated and RenderFrameDestroyed notifications). Find a + // parent that we do know about instead. Note that this is not *always* + // true, because portals are reusable. + if (!frame) + frame = GetFrameNode(render_frame_host->GetParent()); + } else { + opened_type = PageNode::OpenedType::kGuestView; + // For a guest view, the RFH should already have been seen. + + // Note that guest views can simultaneously have openers *and* be embedded. + // The embedded relationship has higher priority, but we'll fall back to + // using the window.open relationship if the embedded relationship is + // severed. + } + DCHECK_NE(PageNode::OpenedType::kInvalid, opened_type); + DCHECK(frame); + + PerformanceManagerImpl::CallOnGraphImpl( + FROM_HERE, base::BindOnce(&PageNodeImpl::SetOpenerFrameNodeAndOpenedType, + base::Unretained(page), base::Unretained(frame), + opened_type)); +} + +void PerformanceManagerTabHelper::InnerWebContentsDetached( + content::WebContents* inner_web_contents) { + auto* helper = FromWebContents(inner_web_contents); + DCHECK(helper); + + // Fall back to using the window.open opener if it exists. If not, simply + // clear the opener relationship entirely. + if (!ConnectWindowOpenRelationshipIfExists(helper, inner_web_contents)) { + PerformanceManagerImpl::CallOnGraphImpl( + FROM_HERE, + base::BindOnce(&PageNodeImpl::ClearOpenerFrameNodeAndOpenedType, + base::Unretained(helper->page_node()))); + } +} + void PerformanceManagerTabHelper::WebContentsDestroyed() { // Remember the contents, as TearDown clears observer. auto* contents = web_contents();
diff --git a/components/performance_manager/performance_manager_tab_helper.h b/components/performance_manager/performance_manager_tab_helper.h index 3582f4d..2ad85365 100644 --- a/components/performance_manager/performance_manager_tab_helper.h +++ b/components/performance_manager/performance_manager_tab_helper.h
@@ -69,6 +69,11 @@ void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; void TitleWasSet(content::NavigationEntry* entry) override; + void InnerWebContentsAttached(content::WebContents* inner_web_contents, + content::RenderFrameHost* render_frame_host, + bool is_full_page) override; + void InnerWebContentsDetached( + content::WebContents* inner_web_contents) override; void WebContentsDestroyed() override; void DidUpdateFaviconURL( const std::vector<blink::mojom::FaviconURLPtr>& candidates) override;
diff --git a/components/performance_manager/public/graph/page_node.h b/components/performance_manager/public/graph/page_node.h index 0cd883a7..422c043 100644 --- a/components/performance_manager/public/graph/page_node.h +++ b/components/performance_manager/public/graph/page_node.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_ #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_ +#include <ostream> #include <string> #include "base/containers/flat_set.h" @@ -33,17 +34,22 @@ using Observer = PageNodeObserver; class ObserverDefaultImpl; - // Reasons for which one frame can become the opener of a page. + // Reasons for which a frame can become the opener of a page. enum class OpenedType { // Returned if this node doesn't have an opener. kInvalid, - // This node is a popup (the opener created it via window.open). + // This page is a popup (the opener created it via window.open). kPopup, - // This node is a guest view. This can be many things (<webview>, <portal>, - // <appview>, etc) but backed by the same inner/outer WebContents mechanism. + // This page is a guest view. This can be many things (<webview>, <appview>, + // etc) but is backed by the same inner/outer WebContents mechanism. kGuestView, + // This page is a portal. + kPortal, }; + // Returns a string for a PageNode::OpenedType enumeration. + static const char* ToString(PageNode::OpenedType opened_type); + PageNode(); ~PageNode() override; @@ -166,9 +172,10 @@ // Notifications of property changes. - // Invoked when this page has been assigned an opener, or had one removed. - // This can happen a page is opened via window.open, webviews, portals, etc, - // or when that relationship is subsequently severed. + // Invoked when this page has been assigned an opener, had the opener change, + // or had the opener removed. This can happen if a page is opened via + // window.open, webviews, portals, etc, or when that relationship is + // subsequently severed or reparented. virtual void OnOpenerFrameNodeChanged(const PageNode* page_node, const FrameNode* previous_opener, OpenedType previous_opened_type) = 0; @@ -260,4 +267,8 @@ } // namespace performance_manager +// std::ostream support for PageNode::OpenedType. +std::ostream& operator<<(std::ostream& os, + performance_manager::PageNode::OpenedType opened_type); + #endif // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_PAGE_NODE_H_
diff --git a/components/performance_manager/test_support/performance_manager_browsertest_harness.cc b/components/performance_manager/test_support/performance_manager_browsertest_harness.cc index 67e3dda..3f21f16 100644 --- a/components/performance_manager/test_support/performance_manager_browsertest_harness.cc +++ b/components/performance_manager/test_support/performance_manager_browsertest_harness.cc
@@ -129,4 +129,9 @@ observer.Wait(); } +void PerformanceManagerBrowserTestHarness::NotifyShellCreated( + content::Shell* shell) { + helper_->OnWebContentsCreated(shell->web_contents()); +} + } // namespace performance_manager
diff --git a/components/performance_manager/test_support/performance_manager_browsertest_harness.h b/components/performance_manager/test_support/performance_manager_browsertest_harness.h index 1a517113..a348dff 100644 --- a/components/performance_manager/test_support/performance_manager_browsertest_harness.h +++ b/components/performance_manager/test_support/performance_manager_browsertest_harness.h
@@ -44,6 +44,10 @@ // Waits for an ongoing navigation to terminate on the given |contents|. void WaitForLoad(content::WebContents* contents); + // Allows tests to notify the harness of shells that were created without + // harness knowledge. This will attach PM tab helpers. + void NotifyShellCreated(content::Shell* shell); + private: std::unique_ptr<PerformanceManagerTestHarnessHelper> helper_; };
diff --git a/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java b/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java index bcd2c19..d2061f5 100644 --- a/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java +++ b/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java
@@ -40,8 +40,15 @@ long startTime = SystemClock.elapsedRealtime(); Bundle bundle = mUserManager.getApplicationRestrictions(packageName); long endTime = SystemClock.elapsedRealtime(); - RecordHistogram.recordTimesHistogram( - "Enterprise.AppRestrictionLoadTime2", endTime - startTime); + long duration = endTime - startTime; + RecordHistogram.recordTimesHistogram("Enterprise.AppRestrictionLoadTime2", duration); + if (bundle.isEmpty()) { + RecordHistogram.recordTimesHistogram( + "Enterprise.AppRestrictionLoadTime2.EmptyBundle", duration); + } else { + RecordHistogram.recordTimesHistogram( + "Enterprise.AppRestrictionLoadTime2.NonEmptyBundle", duration); + } return bundle; } catch (SecurityException e) { // Android bug may throw SecurityException. See crbug.com/886814.
diff --git a/components/test/data/performance_manager/a_popup_a.html b/components/test/data/performance_manager/a_popup_a.html new file mode 100644 index 0000000..9c00221 --- /dev/null +++ b/components/test/data/performance_manager/a_popup_a.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html language="en"> + <head> + <title>a.com</title> + <script language="javascript"> + function onLoad() { + console.log("a_popup_a.html loaded"); + setTimeout( + function () { + let l = window.location; + let url = `${l.protocol}//a.com:${l.port}/a.html`; + console.log(`loading popup [${url}]`); + let w = window.open(url); + }, + 100); + } + </script> + </head> + <body onload="onLoad();"> + Welcome to a.com, with a popup of a.com! + </body> +</html> \ No newline at end of file
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index fdab5d9..926d753 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -19,6 +19,7 @@ sources = [ "resources/resource_format_utils.cc", "resources/resource_format_utils.h", + "resources/resource_format_utils_mac.mm", "resources/resource_sizes.h", "viz_resource_format_export.h", ]
diff --git a/components/viz/common/resources/resource_format_utils.h b/components/viz/common/resources/resource_format_utils.h index ca10863..ce69195 100644 --- a/components/viz/common/resources/resource_format_utils.h +++ b/components/viz/common/resources/resource_format_utils.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_ #define COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_ +#include "build/build_config.h" #include "components/viz/common/resources/resource_format.h" #include "components/viz/common/viz_resource_format_export.h" #include "gpu/vulkan/buildflags.h" @@ -73,6 +74,10 @@ VIZ_RESOURCE_FORMAT_EXPORT WGPUTextureFormat ToWGPUFormat(ResourceFormat format); +#if defined(OS_MACOSX) +VIZ_RESOURCE_FORMAT_EXPORT unsigned int ToMTLPixelFormat(ResourceFormat format); +#endif + } // namespace viz #endif // COMPONENTS_VIZ_COMMON_RESOURCES_RESOURCE_FORMAT_UTILS_H_
diff --git a/components/viz/common/resources/resource_format_utils_mac.mm b/components/viz/common/resources/resource_format_utils_mac.mm new file mode 100644 index 0000000..5a095e7 --- /dev/null +++ b/components/viz/common/resources/resource_format_utils_mac.mm
@@ -0,0 +1,40 @@ +// Copyright 2020 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/viz/common/resources/resource_format_utils.h" + +#include <Metal/MTLPixelFormat.h> + +#include "base/logging.h" + +namespace viz { + +unsigned int ToMTLPixelFormat(ResourceFormat format) { + if (@available(macOS 10.11, *)) { + MTLPixelFormat mtl_pixel_format = MTLPixelFormatInvalid; + switch (format) { + case RED_8: + case ALPHA_8: + case LUMINANCE_8: + mtl_pixel_format = MTLPixelFormatR8Unorm; + break; + case RG_88: + mtl_pixel_format = MTLPixelFormatRG8Unorm; + break; + case RGBA_8888: + mtl_pixel_format = MTLPixelFormatRGBA8Unorm; + break; + case BGRA_8888: + mtl_pixel_format = MTLPixelFormatBGRA8Unorm; + break; + default: + DLOG(ERROR) << "Invalid Metal pixel format."; + break; + } + return static_cast<unsigned int>(mtl_pixel_format); + } + return 0; +} + +} // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc index 9009cbde..b81e8e5 100644 --- a/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc +++ b/components/viz/service/display_embedder/skia_output_device_buffer_queue.cc
@@ -269,8 +269,14 @@ std::make_unique<gpu::SharedImageRepresentationFactory>( dependency_->GetSharedImageManager(), memory_tracker); + // TODO(https://crbug.com/958166): The initial |image_format_| should not be + // used, and the gfx::BufferFormat specified in Reshape should be used + // instead, because it may be updated to reflect changes in the content being + // displayed (e.g, HDR content appearing on-screen). #if defined(USE_OZONE) image_format_ = GetResourceFormat(display::DisplaySnapshot::PrimaryFormat()); +#elif defined(OS_MACOSX) + image_format_ = BGRA_8888; #else image_format_ = RGBA_8888; #endif
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency.h b/components/viz/service/display_embedder/skia_output_surface_dependency.h index d3d814e..a85a0cf 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency.h
@@ -120,6 +120,10 @@ bool IsUsingDawn() const { return gr_context_type() == gpu::GrContextType::kDawn; } + + bool IsUsingMetal() const { + return gr_context_type() == gpu::GrContextType::kMetal; + } }; } // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index f228175..89aa828c 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -885,6 +885,10 @@ wgpu::TextureFormat format = ToDawnFormat(resource_format); return GrBackendFormat::MakeDawn(format); #endif + } else if (dependency_->IsUsingMetal()) { +#if defined(OS_MACOSX) + return GrBackendFormat::MakeMtl(ToMTLPixelFormat(resource_format)); +#endif } else { DCHECK(!ycbcr_info); // Convert internal format from GLES2 to platform GL.
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.cc b/content/browser/accessibility/accessibility_tree_formatter_base.cc index eb115a05..21d1645 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_base.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_base.cc
@@ -38,35 +38,62 @@ // // static -PropertyNode PropertyNode::FromProperty(const base::string16& property) { +PropertyNode PropertyNode::FromPropertyFilter( + const AccessibilityTreeFormatter::PropertyFilter& filter) { + // Property invocation: property_str expected format is + // prop_name or prop_name(arg1, ... argN). PropertyNode root; - Parse(&root, property.begin(), property.end()); + Parse(&root, filter.property_str.begin(), filter.property_str.end()); PropertyNode* node = &root.parameters[0]; - node->original_property = property; + node->original_property = filter.property_str; + + // Line indexes filter: filter_str expected format is + // :line_num_1, ... :line_num_N, a comma separated list of line indexes + // the property should be queried for. For example, ":1,:5,:7" indicates that + // the property should called for objects placed on 1, 5 and 7 lines only. + if (!filter.filter_str.empty()) { + node->line_indexes = + base::SplitString(filter.filter_str, base::string16(1, ','), + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + } + return std::move(*node); } PropertyNode::PropertyNode() = default; PropertyNode::PropertyNode(PropertyNode&& o) - : value(std::move(o.value)), + : name_or_value(std::move(o.name_or_value)), parameters(std::move(o.parameters)), - original_property(std::move(o.original_property)) {} + original_property(std::move(o.original_property)), + line_indexes(std::move(o.line_indexes)) {} PropertyNode::~PropertyNode() = default; PropertyNode& PropertyNode::operator=(PropertyNode&& o) { - value = std::move(o.value); + name_or_value = std::move(o.name_or_value); parameters = std::move(o.parameters); original_property = std::move(o.original_property); + line_indexes = std::move(o.line_indexes); return *this; } PropertyNode::operator bool() const { - return !value.empty(); + return !name_or_value.empty(); } std::string PropertyNode::ToString() const { - std::string out = base::UTF16ToUTF8(value); + std::string out; + for (const auto& index : line_indexes) { + if (!out.empty()) { + out += ','; + } + out += base::UTF16ToUTF8(index); + } + if (!out.empty()) { + out += ';'; + } + + out += base::UTF16ToUTF8(name_or_value); if (parameters.size()) { out += '('; for (size_t i = 0; i < parameters.size(); i++) { @@ -81,10 +108,11 @@ } // private -PropertyNode::PropertyNode(const base::string16& v) : value(v) {} +PropertyNode::PropertyNode(const base::string16& name_or_value) + : name_or_value(name_or_value) {} PropertyNode::PropertyNode(PropertyNode::iterator begin, PropertyNode::iterator end) - : value(begin, end) {} + : name_or_value(begin, end) {} // private static PropertyNode::iterator PropertyNode::Parse(PropertyNode* node, @@ -139,7 +167,26 @@ return iter; } +// // AccessibilityTreeFormatter +// + +AccessibilityTreeFormatter::PropertyFilter::PropertyFilter( + const PropertyFilter&) = default; + +AccessibilityTreeFormatter::PropertyFilter::PropertyFilter( + const base::string16& str, + Type type) + : match_str(str), type(type) { + size_t index = str.find(';'); + if (index != std::string::npos) { + filter_str = str.substr(0, index); + if (index + 1 < str.length()) { + match_str = str.substr(index + 1, std::string::npos); + } + } + property_str = match_str.substr(0, match_str.find('=')); +} AccessibilityTreeFormatter::TestPass AccessibilityTreeFormatter::GetTestPass( size_t index) { @@ -299,24 +346,25 @@ } PropertyNode AccessibilityTreeFormatterBase::GetMatchingPropertyNode( - const base::string16& text) { - // Find the first allow-filter matching the property name. - // The filters have form of name(args)=value. Here we match the name part. - const base::string16 filter_delim = base::ASCIIToUTF16("="); + const base::string16& line_index, + const base::string16& property_name) { + // Find the first allow-filter matching the line index and the property name. for (const auto& filter : property_filters_) { - base::String16Tokenizer filter_tokenizer(filter.match_str, filter_delim); - if (!filter_tokenizer.GetNext()) { + PropertyNode property_node = PropertyNode::FromPropertyFilter(filter); + + // Skip if the line index filter doesn't matched (if specified). + if (!property_node.line_indexes.empty() && + std::find(property_node.line_indexes.begin(), + property_node.line_indexes.end(), + line_index) == property_node.line_indexes.end()) { continue; } - base::string16 property = filter_tokenizer.token(); - PropertyNode property_node = PropertyNode::FromProperty(property); - // The filter should be either an exact property match or a wildcard // matching to support filter collections like AXRole* which matches // AXRoleDescription. - if (text == property_node.value || - base::MatchPattern(text, property_node.value)) { + if (property_name == property_node.name_or_value || + base::MatchPattern(property_name, property_node.name_or_value)) { switch (filter.type) { case PropertyFilter::ALLOW_EMPTY: case PropertyFilter::ALLOW:
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.h b/content/browser/accessibility/accessibility_tree_formatter_base.h index 970462b..884c17940 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_base.h +++ b/content/browser/accessibility/accessibility_tree_formatter_base.h
@@ -37,7 +37,8 @@ class CONTENT_EXPORT PropertyNode final { public: // Parses a property node from a string. - static PropertyNode FromProperty(const base::string16&); + static PropertyNode FromPropertyFilter( + const AccessibilityTreeFormatter::PropertyFilter& filter); PropertyNode(); PropertyNode(PropertyNode&&); @@ -46,13 +47,17 @@ PropertyNode& operator=(PropertyNode&& other); explicit operator bool() const; - base::string16 value; + base::string16 name_or_value; std::vector<PropertyNode> parameters; // Used to store the origianl unparsed property including invocation // parameters if any. base::string16 original_property; + // The list of line indexes of accessible objects the property is allowed to + // be called for. + std::vector<base::string16> line_indexes; + std::string ToString() const; private: @@ -128,7 +133,8 @@ // Returns a property node struct built for a matching property filter, // which includes a property name and invocation parameters if any. // If no matching property filter, then empty property node is returned. - PropertyNode GetMatchingPropertyNode(const base::string16& text); + PropertyNode GetMatchingPropertyNode(const base::string16& line_index, + const base::string16& property_name); // Process accessibility tree with filters for output. // Given a dictionary that contains a platform-specific dictionary
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base_unittest.cc b/content/browser/accessibility/accessibility_tree_formatter_base_unittest.cc index 9c2519a..c43fcf24 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_base_unittest.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_base_unittest.cc
@@ -10,8 +10,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/ax_enums.mojom.h" -#include <iostream> - namespace content { class AccessibilityTreeFormatterBaseTest : public testing::Test { @@ -33,11 +31,15 @@ }; void ParseAndCheck(const char* input, const char* expected) { - auto got = PropertyNode::FromProperty(base::UTF8ToUTF16(input)).ToString(); + AccessibilityTreeFormatter::PropertyFilter filter( + base::UTF8ToUTF16(input), + AccessibilityTreeFormatter::PropertyFilter::ALLOW); + auto got = PropertyNode::FromPropertyFilter(filter).ToString(); EXPECT_EQ(got, expected); } TEST_F(AccessibilityTreeFormatterBaseTest, ParseProperty) { + // Properties and methods. ParseAndCheck("Role", "Role"); ParseAndCheck("ChildAt(3)", "ChildAt(3)"); ParseAndCheck("Cell(3, 4)", "Cell(3, 4)"); @@ -48,6 +50,10 @@ ParseAndCheck("[3, 4]", "[](3, 4)"); ParseAndCheck("Cell([3, 4])", "Cell([](3, 4))"); + // Line indexes filter. + ParseAndCheck(":3,:5;AXDOMClassList", ":3,:5;AXDOMClassList"); + + // Wrong format. ParseAndCheck("Role(3", "Role(3)"); ParseAndCheck("TableFor(CellBy(id", "TableFor(CellBy(id))"); ParseAndCheck("[3, 4", "[](3, 4)");
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/content/browser/accessibility/accessibility_tree_formatter_mac.mm index 0969dd3..1f4917c8 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -50,9 +50,10 @@ } const auto& arraynode = propnode.parameters[0]; - if (arraynode.value != base::ASCIIToUTF16("[]")) { + if (arraynode.name_or_value != base::ASCIIToUTF16("[]")) { LOG(ERROR) << "Failed to parse " << propnode.original_property - << " to IntArray: " << arraynode.value << " is not array"; + << " to IntArray: " << arraynode.name_or_value + << " is not array"; return nil; } @@ -60,9 +61,10 @@ [[NSMutableArray alloc] initWithCapacity:arraynode.parameters.size()]; for (const auto& paramnode : arraynode.parameters) { int param = 0; - if (!base::StringToInt(paramnode.value, ¶m)) { + if (!base::StringToInt(paramnode.name_or_value, ¶m)) { LOG(ERROR) << "Failed to parse " << propnode.original_property - << " to IntArray: " << paramnode.value << " is not a number"; + << " to IntArray: " << paramnode.name_or_value + << " is not a number"; return nil; } [array addObject:@(param)]; @@ -91,7 +93,8 @@ const base::StringPiece& pattern) override; private: - using LineIndexesMap = std::map<const gfx::NativeViewAccessible, int>; + using LineIndexesMap = + std::map<const gfx::NativeViewAccessible, base::string16>; void RecursiveBuildAccessibilityTree(const BrowserAccessibilityCocoa* node, const LineIndexesMap& line_indexes_map, @@ -216,7 +219,9 @@ const BrowserAccessibilityCocoa* cocoa_node, LineIndexesMap* line_indexes_map, int* counter) { - line_indexes_map->insert({cocoa_node, ++(*counter)}); + const base::string16 line_index = + base::string16(1, ':') + base::NumberToString16(++(*counter)); + line_indexes_map->insert({cocoa_node, line_index}); for (BrowserAccessibilityCocoa* cocoa_child in [cocoa_node children]) { RecursiveBuildLineIndexesMap(cocoa_child, line_indexes_map, counter); } @@ -230,10 +235,16 @@ BrowserAccessibility* node = [cocoa_node owner]; dict->SetKey("id", base::Value(base::NumberToString16(node->GetId()))); + base::string16 line_index = base::ASCIIToUTF16("-1"); + if (line_indexes_map.find(cocoa_node) != line_indexes_map.end()) { + line_index = line_indexes_map.at(cocoa_node); + } + // Attributes for (NSString* supportedAttribute in [cocoa_node accessibilityAttributeNames]) { - if (GetMatchingPropertyNode(SysNSStringToUTF16(supportedAttribute))) { + if (GetMatchingPropertyNode(line_index, + SysNSStringToUTF16(supportedAttribute))) { id value = [cocoa_node accessibilityAttributeValue:supportedAttribute]; if (value != nil) { dict->SetPath(SysNSStringToUTF8(supportedAttribute), @@ -246,9 +257,9 @@ for (NSString* supportedAttribute in [cocoa_node accessibilityParameterizedAttributeNames]) { id param = nil; - auto propnode = - GetMatchingPropertyNode(SysNSStringToUTF16(supportedAttribute)); - if (propnode.value == base::ASCIIToUTF16("AXCellForColumnAndRow")) { + auto propnode = GetMatchingPropertyNode( + line_index, SysNSStringToUTF16(supportedAttribute)); + if (propnode.name_or_value == base::ASCIIToUTF16("AXCellForColumnAndRow")) { param = PropNodeToIntArray(propnode); if (param == nil) { dict->SetPath(base::UTF16ToUTF8(propnode.original_property), @@ -324,11 +335,11 @@ // Accessible object. if ([value isKindOfClass:[BrowserAccessibilityCocoa class]]) { - int line_index = -1; + base::string16 line_index = base::ASCIIToUTF16("-1"); if (line_indexes_map.find(value) != line_indexes_map.end()) { line_index = line_indexes_map.at(value); } - return base::Value(":" + base::NumberToString(line_index)); + return base::Value(line_index); } // Scalar value.
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm index d36c275c..353790a 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm +++ b/content/browser/accessibility/accessibility_tree_formatter_mac_browsertest.mm
@@ -93,6 +93,20 @@ } IN_PROC_BROWSER_TEST_F(AccessibilityTreeFormatterMacBrowserTest, + Attributes_LineIndexFilter) { + TestAndCheck(R"~~(data:text/html, + <input class='input_at_3rd_line'> + <input class='input_at_4th_line'> + <input class='input_at_5th_line'>)~~", + {":3,:5;AXDOMClassList=*"}, R"~~(AXWebArea +++AXGroup +++++AXTextField AXDOMClassList=['input_at_3rd_line'] +++++AXTextField +++++AXTextField AXDOMClassList=['input_at_5th_line'] +)~~"); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityTreeFormatterMacBrowserTest, ParameterizedAttributes) { TestAndCheck(R"~~(data:text/html, <table role="grid"><tr><td>CELL</td></tr></table>)~~",
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc index a65e37e..6ba53272 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -70,7 +70,7 @@ // datatypes, |embedder_matcher| must not be null; the decision for those // datatypes will be delegated to it. bool DoesOriginMatchMaskAndPredicate( - int origin_type_mask, + uint64_t origin_type_mask, base::OnceCallback<bool(const url::Origin&)> predicate, const BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher& embedder_matcher, @@ -112,8 +112,8 @@ BrowsingDataRemoverImpl::BrowsingDataRemoverImpl( BrowserContext* browser_context) : browser_context_(browser_context), - remove_mask_(-1), - origin_type_mask_(-1), + remove_mask_(0xffffffffffffffffull), + origin_type_mask_(0xffffffffffffffffull), is_removing_(false), storage_partition_for_testing_(nullptr) { DCHECK(browser_context_); @@ -152,7 +152,7 @@ } bool BrowsingDataRemoverImpl::DoesOriginMatchMaskForTesting( - int origin_type_mask, + uint64_t origin_type_mask, const url::Origin& origin, storage::SpecialStoragePolicy* policy) { BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher embedder_matcher; @@ -166,16 +166,16 @@ void BrowsingDataRemoverImpl::Remove(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask) { + uint64_t remove_mask, + uint64_t origin_type_mask) { RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder>(), nullptr); } void BrowsingDataRemoverImpl::RemoveAndReply(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, Observer* observer) { DCHECK(observer); RemoveInternal(delete_begin, delete_end, remove_mask, origin_type_mask, @@ -185,8 +185,8 @@ void BrowsingDataRemoverImpl::RemoveWithFilterAndReply( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer) { DCHECK(filter_builder); @@ -198,8 +198,8 @@ void BrowsingDataRemoverImpl::RemoveInternal( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer) { DCHECK(!observer || observer_list_.HasObserver(observer)) @@ -258,9 +258,9 @@ void BrowsingDataRemoverImpl::RemoveImpl( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask) { + uint64_t origin_type_mask) { // =============== README before adding more storage backends =============== // // If you're adding a data storage backend that is included among @@ -562,19 +562,19 @@ return delete_begin_; } -int BrowsingDataRemoverImpl::GetLastUsedRemovalMaskForTesting() { +uint64_t BrowsingDataRemoverImpl::GetLastUsedRemovalMaskForTesting() { return remove_mask_; } -int BrowsingDataRemoverImpl::GetLastUsedOriginTypeMaskForTesting() { +uint64_t BrowsingDataRemoverImpl::GetLastUsedOriginTypeMaskForTesting() { return origin_type_mask_; } BrowsingDataRemoverImpl::RemovalTask::RemovalTask( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer) : delete_begin(delete_begin),
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.h b/content/browser/browsing_data/browsing_data_remover_impl.h index 34357d2..1f6fec7 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl.h +++ b/content/browser/browsing_data/browsing_data_remover_impl.h
@@ -43,23 +43,23 @@ void SetEmbedderDelegate( BrowsingDataRemoverDelegate* embedder_delegate) override; bool DoesOriginMatchMaskForTesting( - int origin_type_mask, + uint64_t origin_type_mask, const url::Origin& origin, storage::SpecialStoragePolicy* special_storage_policy) override; void Remove(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask) override; + uint64_t remove_mask, + uint64_t origin_type_mask) override; void RemoveAndReply(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, Observer* observer) override; void RemoveWithFilterAndReply( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer) override; @@ -71,8 +71,8 @@ void(base::OnceClosure continue_to_completion)>& callback) override; const base::Time& GetLastUsedBeginTimeForTesting() override; - int GetLastUsedRemovalMaskForTesting() override; - int GetLastUsedOriginTypeMaskForTesting() override; + uint64_t GetLastUsedRemovalMaskForTesting() override; + uint64_t GetLastUsedOriginTypeMaskForTesting() override; // Used for testing. void OverrideStoragePartitionForTesting(StoragePartition* storage_partition); @@ -82,8 +82,8 @@ virtual void RemoveInternal( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer); @@ -118,8 +118,8 @@ struct CONTENT_EXPORT RemovalTask { RemovalTask(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer); RemovalTask(RemovalTask&& other) noexcept; @@ -131,8 +131,8 @@ base::Time delete_begin; base::Time delete_end; - int remove_mask; - int origin_type_mask; + uint64_t remove_mask; + uint64_t origin_type_mask; std::unique_ptr<BrowsingDataFilterBuilder> filter_builder; std::vector<Observer*> observers; base::Time task_started; @@ -156,9 +156,9 @@ // TODO(crbug.com/589586): Support all backends w/ origin filter. void RemoveImpl(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask); + uint64_t origin_type_mask); // Notifies observers and transitions to the idle state. void Notify(); @@ -198,10 +198,10 @@ base::Time delete_end_; // The removal mask for the current removal operation. - int remove_mask_ = 0; + uint64_t remove_mask_ = 0; // From which types of origins should we remove data? - int origin_type_mask_ = 0; + uint64_t origin_type_mask_ = 0; // True if Remove has been invoked. bool is_removing_;
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc index 8552434..4d99509 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
@@ -96,7 +96,7 @@ void SetUpOnMainThread() override {} - void RemoveAndWait(int remove_mask) { + void RemoveAndWait(uint64_t remove_mask) { content::BrowsingDataRemover* remover = content::BrowserContext::GetBrowsingDataRemover( shell()->web_contents()->GetBrowserContext()); @@ -109,7 +109,7 @@ } void RemoveWithFilterAndWait( - int remove_mask, + uint64_t remove_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter) { content::BrowsingDataRemover* remover = content::BrowserContext::GetBrowsingDataRemover(
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc index 16722e3f..0e34ae74 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -331,7 +331,7 @@ void BlockUntilBrowsingDataRemoved(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, bool include_protected_origins) { // TODO(msramek): Consider moving |storage_partition| to the test fixture. StoragePartitionRemovalTestStoragePartition storage_partition; @@ -342,7 +342,8 @@ remover_->OverrideStoragePartitionForTesting(&storage_partition); - int origin_type_mask = BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; + uint64_t origin_type_mask = + BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB; if (include_protected_origins) origin_type_mask |= BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; @@ -359,7 +360,7 @@ void BlockUntilOriginDataRemoved( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder) { StoragePartitionRemovalTestStoragePartition storage_partition; @@ -389,9 +390,11 @@ return remover_->GetLastUsedBeginTimeForTesting(); } - int GetRemovalMask() { return remover_->GetLastUsedRemovalMaskForTesting(); } + uint64_t GetRemovalMask() { + return remover_->GetLastUsedRemovalMaskForTesting(); + } - int GetOriginTypeMask() { + uint64_t GetOriginTypeMask() { return remover_->GetLastUsedOriginTypeMaskForTesting(); } @@ -413,7 +416,7 @@ } bool Match(const GURL& origin, - int mask, + uint64_t mask, storage::SpecialStoragePolicy* policy) { return remover_->DoesOriginMatchMaskForTesting( mask, url::Origin::Create(origin), policy); @@ -632,8 +635,8 @@ EXPECT_CALL(*downloads_tester.download_manager(), RemoveDownloadsByURLAndTime(_, _, _)); - int removal_mask = BrowsingDataRemover::DATA_TYPE_DOWNLOADS | - BrowsingDataRemover::DATA_TYPE_COOKIES; + uint64_t removal_mask = BrowsingDataRemover::DATA_TYPE_DOWNLOADS | + BrowsingDataRemover::DATA_TYPE_COOKIES; BlockUntilBrowsingDataRemoved(base::Time(), base::Time::Max(), removal_mask, false); @@ -1474,7 +1477,7 @@ BrowserContext::GetBrowsingDataRemover(GetBrowserContext())); EXPECT_FALSE(remover->IsRemovingForTesting()); - int test_removal_masks[] = { + uint64_t test_removal_masks[] = { BrowsingDataRemover::DATA_TYPE_COOKIES, BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, BrowsingDataRemover::DATA_TYPE_COOKIES, @@ -1494,7 +1497,7 @@ BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, }; - for (int removal_mask : test_removal_masks) { + for (uint64_t removal_mask : test_removal_masks) { remover->Remove(base::Time(), base::Time::Max(), removal_mask, BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB); }
diff --git a/content/browser/browsing_data/clear_site_data_handler_browsertest.cc b/content/browser/browsing_data/clear_site_data_handler_browsertest.cc index 5bd657d..c767f7b 100644 --- a/content/browser/browsing_data/clear_site_data_handler_browsertest.cc +++ b/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
@@ -87,12 +87,12 @@ bool cookies, bool storage, bool cache) { - const int kOriginTypeMask = + const uint64_t kOriginTypeMask = BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; if (cookies) { - int data_type_mask = + uint64_t data_type_mask = BrowsingDataRemover::DATA_TYPE_COOKIES | BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS; @@ -103,7 +103,7 @@ kOriginTypeMask, &filter_builder); } if (storage || cache) { - int data_type_mask = + uint64_t data_type_mask = (storage ? BrowsingDataRemover::DATA_TYPE_DOM_STORAGE : 0) | (cache ? BrowsingDataRemover::DATA_TYPE_CACHE : 0);
diff --git a/content/browser/browsing_data/clear_site_data_utils.cc b/content/browser/browsing_data/clear_site_data_utils.cc index c17c186..350c32e 100644 --- a/content/browser/browsing_data/clear_site_data_utils.cc +++ b/content/browser/browsing_data/clear_site_data_utils.cc
@@ -75,7 +75,7 @@ domain_filter_builder->AddRegisterableDomain(domain); pending_task_count_++; - int remove_mask = BrowsingDataRemover::DATA_TYPE_COOKIES; + uint64_t remove_mask = BrowsingDataRemover::DATA_TYPE_COOKIES; if (avoid_closing_connections_) { remove_mask |= BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS; } @@ -87,7 +87,7 @@ } // Delete origin-scoped data. - int remove_mask = 0; + uint64_t remove_mask = 0; if (clear_storage_) remove_mask |= BrowsingDataRemover::DATA_TYPE_DOM_STORAGE; if (clear_cache_)
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index f576993..914d8ffb 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -3092,10 +3092,17 @@ navigation_handle_timing_->first_response_start_time = response_head_->load_timing.receive_headers_start; } - if (navigation_handle_timing_->first_loader_callback_time.is_null()) { + base::TimeTicks loader_callback_time = base::TimeTicks::Now(); + if (navigation_handle_timing_->first_loader_callback_time.is_null()) navigation_handle_timing_->first_loader_callback_time = - base::TimeTicks::Now(); - } + loader_callback_time; + + navigation_handle_timing_->final_request_start_time = + response_head_->load_timing.send_start; + navigation_handle_timing_->final_response_start_time = + response_head_->load_timing.receive_headers_start; + navigation_handle_timing_->final_loader_callback_time = loader_callback_time; + // |navigation_commit_sent_time| will be updated by // UpdateNavigationHandleTimingsOnCommitSent() later. DCHECK(navigation_handle_timing_->navigation_commit_sent_time.is_null());
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 111129f1..ea3b133 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -488,17 +488,43 @@ base::debug::SetCrashKeyString(failure_reason_key, failure_reason); } -url::Origin GetOriginForURLLoaderFactoryUnchecked( - NavigationRequest* navigation_request) { - // Return a safe opaque origin when there is no |navigation_request| - if (!navigation_request) - return url::Origin(); +bool ShouldBypassChecksForErrorPage( + RenderFrameHostImpl* frame, + NavigationRequest* navigation_request, + bool* should_commit_unreachable_url = nullptr) { + DCHECK(frame); - // GetOriginForURLLoaderFactory should only be called at the ready-to-commit - // time, when the RFHI to commit the navigation is already known. - DCHECK_LE(NavigationRequest::READY_TO_COMMIT, navigation_request->state()); - RenderFrameHostImpl* target_frame = navigation_request->GetRenderFrameHost(); + if (should_commit_unreachable_url) + *should_commit_unreachable_url = false; + + bool is_main_frame = !frame->GetParent(); + if (SiteIsolationPolicy::IsErrorPageIsolationEnabled(is_main_frame)) { + if (frame->GetSiteInstance()->GetSiteURL() == + GURL(content::kUnreachableWebDataURL)) { + if (should_commit_unreachable_url) + *should_commit_unreachable_url = true; + + // With error page isolation, any URL can commit in an error page process. + return true; + } + } else { + // Without error page isolation, a blocked navigation is expected to + // commit in the old renderer process. This may be true for subframe + // navigations even when error page isolation is enabled for main frames. + if (navigation_request && + navigation_request->GetNetErrorCode() == net::ERR_BLOCKED_BY_CLIENT) { + return true; + } + } + + return false; +} + +url::Origin GetOriginForURLLoaderFactoryUnchecked( + RenderFrameHostImpl* target_frame, + NavigationRequest* navigation_request) { DCHECK(target_frame); + DCHECK(navigation_request); // Check if this is loadDataWithBaseUrl (which needs special treatment). auto& common_params = navigation_request->common_params(); @@ -547,18 +573,29 @@ url::Origin GetOriginForURLLoaderFactory( NavigationRequest* navigation_request) { + // Return a safe opaque origin when there is no |navigation_request| (e.g. + // when RFHI::CommitNavigation is called via RFHI::NavigateToInterstitialURL). + if (!navigation_request) + return url::Origin(); + + // GetOriginForURLLoaderFactory should only be called at the ReadyToCommit + // time, when the RFHI to commit the navigation is already known. + DCHECK_EQ(NavigationRequest::READY_TO_COMMIT, navigation_request->state()); + RenderFrameHostImpl* target_frame = navigation_request->GetRenderFrameHost(); + DCHECK(target_frame); + + // Calculate an approximation (sandbox/csp is ignored) of the origin that will + // be committed because of |navigation_request|. url::Origin result = - GetOriginForURLLoaderFactoryUnchecked(navigation_request); + GetOriginForURLLoaderFactoryUnchecked(target_frame, navigation_request); - // |result| must be an origin that is allowed to be accessed from the process - // that is the target of this navigation. - if (navigation_request) { - int process_id = - navigation_request->GetRenderFrameHost()->GetProcess()->GetID(); - auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); - CHECK(policy->CanAccessDataForOrigin(process_id, result)); - } - + // Check that |result| origin is allowed to be accessed from the process that + // is the target of this navigation. + if (ShouldBypassChecksForErrorPage(target_frame, navigation_request)) + return result; + int process_id = target_frame->GetProcess()->GetID(); + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + CHECK(policy->CanAccessDataForOrigin(process_id, result)); return result; } @@ -3162,8 +3199,9 @@ // Validate the URLs in |params|. If the renderer can't request the URLs // directly, don't show them in the context menu. ContextMenuParams validated_params(params); - validated_params.frame_url = GetLastCommittedURL(); validated_params.page_url = GetMainFrame()->GetLastCommittedURL(); + if (GetParent()) // Only populate |frame_url| for subframes. + validated_params.frame_url = GetLastCommittedURL(); // We don't validate |unfiltered_link_url| so that this field can be used // when users want to copy the original link URL. @@ -4724,7 +4762,14 @@ // window.open() will return "window" and navigate it to whatever URL was // passed. if (!render_view_host_->GetWebkitPreferences().supports_multiple_windows) { - std::move(callback).Run(mojom::CreateNewWindowStatus::kReuse, nullptr); + // See crbug.com/1083819, we should ignore if the URL is javascript: scheme, + // previously we already filtered out javascript: scheme and replace the + // URL with |kBlockedURL|, so we check against |kBlockedURL| here. + if (params->target_url == GURL(kBlockedURL)) { + std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr); + } else { + std::move(callback).Run(mojom::CreateNewWindowStatus::kReuse, nullptr); + } return; } @@ -7714,30 +7759,18 @@ // Error pages may sometimes commit a URL in the wrong process, which requires // an exception for the CanCommitOriginAndUrl() checks. This is ok as long // as the origin is opaque. - bool bypass_checks_for_error_page = false; - if (SiteIsolationPolicy::IsErrorPageIsolationEnabled( - frame_tree_node_->IsMainFrame())) { - if (site_instance_->GetSiteURL() == GURL(content::kUnreachableWebDataURL)) { - // Commits in the error page process must only be failures, otherwise - // successful navigations could commit documents from origins different - // than the chrome-error://chromewebdata/ one and violate expectations. - if (!params->url_is_unreachable) { - DEBUG_ALIAS_FOR_ORIGIN(origin_debug_alias, params->origin); - bad_message::ReceivedBadMessage( - process, bad_message::RFH_ERROR_PROCESS_NON_ERROR_COMMIT); - return false; - } - // With error page isolation, any URL can commit in an error page process. - bypass_checks_for_error_page = true; - } - } else { - // Without error page isolation, a blocked navigation is expected to - // commit in the old renderer process. This may be true for subframe - // navigations even when error page isolation is enabled for main frames. - if (navigation_request && - navigation_request->GetNetErrorCode() == net::ERR_BLOCKED_BY_CLIENT) { - bypass_checks_for_error_page = true; - } + bool should_commit_unreachable_url = false; + bool bypass_checks_for_error_page = ShouldBypassChecksForErrorPage( + this, navigation_request, &should_commit_unreachable_url); + + // Commits in the error page process must only be failures, otherwise + // successful navigations could commit documents from origins different + // than the chrome-error://chromewebdata/ one and violate expectations. + if (should_commit_unreachable_url && !params->url_is_unreachable) { + DEBUG_ALIAS_FOR_ORIGIN(origin_debug_alias, params->origin); + bad_message::ReceivedBadMessage( + process, bad_message::RFH_ERROR_PROCESS_NON_ERROR_COMMIT); + return false; } // Error pages must commit in a opaque origin. Terminate the renderer
diff --git a/content/browser/renderer_host/display_util.cc b/content/browser/renderer_host/display_util.cc index 9ee2ff10..b8b0c23 100644 --- a/content/browser/renderer_host/display_util.cc +++ b/content/browser/renderer_host/display_util.cc
@@ -53,21 +53,7 @@ // static void DisplayUtil::GetDefaultScreenInfo(ScreenInfo* screen_info) { - // Some tests are run with no Screen initialized. - display::Screen* screen = display::Screen::GetScreen(); - if (!screen) { - *screen_info = ScreenInfo(); - return; - } -#if defined(USE_AURA) - // This behavior difference between Aura and other platforms may or may not - // be intentional, and may or may not have any effect. - gfx::NativeView null_native_view = nullptr; - display::Display display = screen->GetDisplayNearestView(null_native_view); -#else - display::Display display = screen->GetPrimaryDisplay(); -#endif - DisplayToScreenInfo(screen_info, display); + return GetNativeViewScreenInfo(screen_info, nullptr); } // static
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 691b67f..e80992b 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1671,6 +1671,10 @@ input_router_->SetDeviceScaleFactor(result->device_scale_factor); } +base::Optional<cc::TouchAction> RenderWidgetHostImpl::GetAllowedTouchAction() { + return input_router_->AllowedTouchAction(); +} + void RenderWidgetHostImpl::DragTargetDragEnter( const DropData& drop_data, const gfx::PointF& client_pt,
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 890f2ba..e051cb5 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -228,6 +228,7 @@ void AddObserver(RenderWidgetHostObserver* observer) override; void RemoveObserver(RenderWidgetHostObserver* observer) override; void GetScreenInfo(content::ScreenInfo* result) override; + base::Optional<cc::TouchAction> GetAllowedTouchAction() override; // |drop_data| must have been filtered. The embedder should call // FilterDropData before passing the drop data to RWHI. void DragTargetDragEnter(const DropData& drop_data,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index b89bdda..1a55839 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1890,10 +1890,17 @@ DCHECK_EQ(1u, node_.GetInnerWebContents().size()); inner_web_contents_impl->SetAsFocusedWebContentsIfNecessary(); } + + for (auto& observer : observers_) { + observer.InnerWebContentsAttached(inner_web_contents_impl, + render_frame_host, is_full_page); + } } std::unique_ptr<WebContents> WebContentsImpl::DetachFromOuterWebContents() { - DCHECK(node_.outer_web_contents()); + auto* outer_web_contents = GetOuterWebContents(); + DCHECK(outer_web_contents); + RecursivelyUnregisterFrameSinkIds(); if (RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(GetMainFrame()->GetView())) { @@ -1929,6 +1936,11 @@ // used for portals, or it should get a different name. GetMainFrame()->set_browser_plugin_embedder_ax_tree_id(ui::AXTreeIDUnknown()); GetMainFrame()->UpdateAXTreeData(); + + // Invoke on the *outer* web contents observers for symmetry. + for (auto& observer : outer_web_contents->observers_) + observer.InnerWebContentsDetached(this); + return web_contents; }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 2aaacff..0933d86c 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -323,7 +323,8 @@ device::kWebAuthGetAssertionFeaturePolicy, kUseFeatureState}, {wf::EnableTransformInterop, blink::features::kTransformInterop, kUseFeatureState}, - + {wf::EnableVideoWakeLockOptimisationHiddenMuted, + media::kWakeLockOptimisationHiddenMuted, kUseFeatureState}, }; for (const auto& mapping : blinkFeatureToBaseFeatureMapping) { SetRuntimeFeatureFromChromiumFeature(
diff --git a/content/public/browser/accessibility_tree_formatter.h b/content/public/browser/accessibility_tree_formatter.h index cecbbe4..b954cce0 100644 --- a/content/public/browser/accessibility_tree_formatter.h +++ b/content/public/browser/accessibility_tree_formatter.h
@@ -56,15 +56,31 @@ class CONTENT_EXPORT AccessibilityTreeFormatter : public AccessibilityTestExpectationsLocator { public: - // A single property filter specification. See GetAllowString() and - // GetDenyString() for more information. - struct PropertyFilter { + // A single property filter specification. Represents a parsed string of the + // filter_str;match_str format, where `filter_str` has + // :line_num_0,...:line_num_N format, `match_str` has format of + // property_str=value_str. For example, :1,:3;AXDOMClassList=*. + // + // Longer version: `filter_str` is a comma separated list of the line + // indexes from the output accessible tree, and serves to narrow down the + // property calls to the accessible object placed on those line indexes only; + // `match_str` is used to match properties by property name and value. + // For example, :1,:3;AXDOMClassList=* + // will query a AXDOMClassList attribute on accessible objects placed at 1st + // and 3rd lines in the output accessible tree. + // Also see + // DumpAccessibilityTestBase::ParseHtmlForExtraDirectives() for more + // information. + struct CONTENT_EXPORT PropertyFilter { enum Type { ALLOW, ALLOW_EMPTY, DENY }; + base::string16 match_str; + base::string16 property_str; + base::string16 filter_str; Type type; - PropertyFilter(base::string16 match_str, Type type) - : match_str(match_str), type(type) {} + PropertyFilter(const base::string16& str, Type type); + PropertyFilter(const PropertyFilter&); }; // A single node filter specification which will exclude any node where the
diff --git a/content/public/browser/browsing_data_remover.h b/content/public/browser/browsing_data_remover.h index 586ecaa5..3d474a76 100644 --- a/content/public/browser/browsing_data_remover.h +++ b/content/public/browser/browsing_data_remover.h
@@ -63,7 +63,7 @@ class BrowsingDataRemover { public: // Mask used for Remove. - enum DataType { + enum DataType : uint64_t { // Storage datatypes. DATA_TYPE_APP_CACHE = 1 << 0, DATA_TYPE_FILE_SYSTEMS = 1 << 1, @@ -115,7 +115,7 @@ DATA_TYPE_CONTENT_END = DATA_TYPE_CONVERSIONS, }; - enum OriginType { + enum OriginType : uint64_t { // Web storage origins that StoragePartition recognizes as NOT protected // according to its special storage policy. ORIGIN_TYPE_UNPROTECTED_WEB = 1 << 0, @@ -159,7 +159,7 @@ // Determines whether |origin| matches the |origin_type_mask| according to // the |special_storage_policy|. virtual bool DoesOriginMatchMaskForTesting( - int origin_type_mask, + uint64_t origin_type_mask, const url::Origin& origin, storage::SpecialStoragePolicy* special_storage_policy) = 0; @@ -167,15 +167,15 @@ // specified by |remove_mask| and origin types by |origin_type_mask|. virtual void Remove(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask) = 0; + uint64_t remove_mask, + uint64_t origin_type_mask) = 0; // A version of the above that in addition informs the |observer| when the // removal task is finished. virtual void RemoveAndReply(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, Observer* observer) = 0; // A version of the above that in addition informs the |observer| when the @@ -183,8 +183,8 @@ virtual void RemoveWithFilterAndReply( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, Observer* observer) = 0; @@ -207,8 +207,8 @@ // consider simplifying this interface by removing these methods and changing // the tests to record the parameters using GMock instead. virtual const base::Time& GetLastUsedBeginTimeForTesting() = 0; - virtual int GetLastUsedRemovalMaskForTesting() = 0; - virtual int GetLastUsedOriginTypeMaskForTesting() = 0; + virtual uint64_t GetLastUsedRemovalMaskForTesting() = 0; + virtual uint64_t GetLastUsedOriginTypeMaskForTesting() = 0; }; } // namespace content
diff --git a/content/public/browser/browsing_data_remover_delegate.h b/content/public/browser/browsing_data_remover_delegate.h index 4774cb1..a16c544 100644 --- a/content/public/browser/browsing_data_remover_delegate.h +++ b/content/public/browser/browsing_data_remover_delegate.h
@@ -28,7 +28,7 @@ // Determines whether |origin| matches |origin_type_mask| given // the |special_storage_policy|. using EmbedderOriginTypeMatcher = - base::RepeatingCallback<bool(int origin_type_mask, + base::RepeatingCallback<bool(uint64_t origin_type_mask, const url::Origin& origin, storage::SpecialStoragePolicy* policy)>; @@ -47,9 +47,9 @@ // Removes embedder-specific data. virtual void RemoveEmbedderData(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask, + uint64_t origin_type_mask, base::OnceClosure callback) = 0; };
diff --git a/content/public/browser/navigation_handle_timing.h b/content/public/browser/navigation_handle_timing.h index 913839d..295e158 100644 --- a/content/public/browser/navigation_handle_timing.h +++ b/content/public/browser/navigation_handle_timing.h
@@ -45,6 +45,35 @@ // the navigation loader receiving it. base::TimeTicks first_loader_callback_time; + // The time the final HTTP request was sent. This is filled with + // net::LoadTimingInfo::send_start during navigation. + // + // In some cases, this can be the time an internal request started that did + // not go to the networking layer. See the comment for + // |first_request_start_time|. + // + // This is equal to |first_request_start_time| if there is no redirection. + base::TimeTicks final_request_start_time; + + // The time the headers of the final HTTP response were received. This is + // filled with net::LoadTimingInfo::receive_headers_start on the final HTTP + // response during navigation. + // + // In some cases, this can be the time an internal response was received that + // did not come from the networking layer. See the comment for + // |first_response_start_time|. + // + // This is equal to |first_response_start_time| if there is no redirection. + base::TimeTicks final_response_start_time; + + // The time a callback for the navigation loader was last invoked. The time + // between this and |final_response_start_time| includes any throttling or + // process/thread hopping between the network stack receiving the response and + // the navigation loader receiving it. + // + // This is equal to |first_loader_callback_time| if there is no redirection. + base::TimeTicks final_loader_callback_time; + // The time the navigation commit message was sent to a renderer process. base::TimeTicks navigation_commit_sent_time; };
diff --git a/content/public/browser/render_widget_host.h b/content/public/browser/render_widget_host.h index 6c065e0..d930028fe5 100644 --- a/content/public/browser/render_widget_host.h +++ b/content/public/browser/render_widget_host.h
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/i18n/rtl.h" +#include "base/optional.h" #include "build/build_config.h" #include "content/common/content_export.h" #include "content/public/browser/native_web_keyboard_event.h" @@ -30,6 +31,10 @@ class WebMouseWheelEvent; } +namespace cc { +enum class TouchAction; +} + namespace gfx { class Point; } @@ -278,6 +283,9 @@ // Get the screen info corresponding to this render widget. virtual void GetScreenInfo(ScreenInfo* result) = 0; + // Get the allowed touch action corresponding to this render widget. + virtual base::Optional<cc::TouchAction> GetAllowedTouchAction() = 0; + // Drag-and-drop drop target messages that get sent to Blink. virtual void DragTargetDragEnter( const DropData& drop_data,
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index da2c6572..647ac77 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -427,6 +427,20 @@ // added to the WebContents tree at this point, but can be observed safely. virtual void InnerWebContentsCreated(WebContents* inner_web_contents) {} + // Notifies that an |inner_web_contents| instance has been attached to the + // provided |render_frame_host|. By the time this is called the + // |inner_web_contents| will have been added to the WebContents tree. + virtual void InnerWebContentsAttached(WebContents* inner_web_contents, + RenderFrameHost* render_frame_host, + bool is_full_page) {} + + // Notifies that an |inner_web_contents| instance has been detached from this + // WebContents. InnerWebContentsAttached() will already have been called for + // the |inner_web_contents|. By the time this is called the + // |inner_web_contents| will have been removed from the WebContents tree, but + // will still be alive and is safe to observe. + virtual void InnerWebContentsDetached(WebContents* inner_web_contents) {} + // Invoked when WebContents::Clone() was used to clone a WebContents. virtual void DidCloneToNewWebContents(WebContents* old_web_contents, WebContents* new_web_contents) {}
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index 258ea98b..0992e717 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -244,7 +244,6 @@ IPC_STRUCT_TRAITS_MEMBER(picture_in_picture_enabled) IPC_STRUCT_TRAITS_MEMBER(translate_service_available) IPC_STRUCT_TRAITS_MEMBER(network_quality_estimator_web_holdback) - IPC_STRUCT_TRAITS_MEMBER(lazy_load_enabled) IPC_STRUCT_TRAITS_MEMBER(lazy_frame_loading_distance_thresholds_px) IPC_STRUCT_TRAITS_MEMBER(lazy_image_loading_distance_thresholds_px) IPC_STRUCT_TRAITS_MEMBER(lazy_image_first_k_fully_load)
diff --git a/content/public/test/mock_browsing_data_remover_delegate.cc b/content/public/test/mock_browsing_data_remover_delegate.cc index d11cac3..e161647 100644 --- a/content/public/test/mock_browsing_data_remover_delegate.cc +++ b/content/public/test/mock_browsing_data_remover_delegate.cc
@@ -28,9 +28,9 @@ void MockBrowsingDataRemoverDelegate::RemoveEmbedderData( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask, + uint64_t origin_type_mask, base::OnceClosure callback) { actual_calls_.emplace_back(delete_begin, delete_end, remove_mask, origin_type_mask, filter_builder->Copy(), @@ -41,8 +41,8 @@ void MockBrowsingDataRemoverDelegate::ExpectCall( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, BrowsingDataFilterBuilder* filter_builder) { expected_calls_.emplace_back(delete_begin, delete_end, remove_mask, origin_type_mask, filter_builder->Copy(), @@ -52,8 +52,8 @@ void MockBrowsingDataRemoverDelegate::ExpectCallDontCareAboutFilterBuilder( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask) { + uint64_t remove_mask, + uint64_t origin_type_mask) { expected_calls_.emplace_back( delete_begin, delete_end, remove_mask, origin_type_mask, BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::BLACKLIST), @@ -81,8 +81,8 @@ MockBrowsingDataRemoverDelegate::CallParameters::CallParameters( const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, bool should_compare_filter) : delete_begin_(delete_begin),
diff --git a/content/public/test/mock_browsing_data_remover_delegate.h b/content/public/test/mock_browsing_data_remover_delegate.h index 778cfc6..4d923703 100644 --- a/content/public/test/mock_browsing_data_remover_delegate.h +++ b/content/public/test/mock_browsing_data_remover_delegate.h
@@ -26,23 +26,23 @@ bool MayRemoveDownloadHistory() override; void RemoveEmbedderData(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, + uint64_t remove_mask, BrowsingDataFilterBuilder* filter_builder, - int origin_type_mask, + uint64_t origin_type_mask, base::OnceClosure callback) override; // Add an expected call for testing. void ExpectCall(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, BrowsingDataFilterBuilder* filter_builder); // Add an expected call that doesn't have to match the filter_builder. void ExpectCallDontCareAboutFilterBuilder(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask); + uint64_t remove_mask, + uint64_t origin_type_mask); // Verify that expected and actual calls match. void VerifyAndClearExpectations(); @@ -52,8 +52,8 @@ public: CallParameters(const base::Time& delete_begin, const base::Time& delete_end, - int remove_mask, - int origin_type_mask, + uint64_t remove_mask, + uint64_t origin_type_mask, std::unique_ptr<BrowsingDataFilterBuilder> filter_builder, bool should_compare_filter); ~CallParameters(); @@ -66,8 +66,8 @@ base::Time delete_begin_; base::Time delete_end_; - int remove_mask_; - int origin_type_mask_; + uint64_t remove_mask_; + uint64_t origin_type_mask_; std::unique_ptr<BrowsingDataFilterBuilder> filter_builder_; bool should_compare_filter_; };
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 2f14e71..24b3c33 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -688,9 +688,18 @@ void RenderFrameProxy::SetLayer(scoped_refptr<cc::Layer> layer, bool prevent_contents_opaque_changes, bool is_surface_layer) { + // |ancestor_render_widget_| can be null if this is a proxy for a remote main + // frame, or a subframe of that proxy. However, we should not be setting a + // layer on such a proxy (the layer is used for embedding a child proxy). + DCHECK(ancestor_render_widget_); + if (web_frame()) { web_frame()->SetCcLayer(layer.get(), prevent_contents_opaque_changes, is_surface_layer); + + // Schedule an animation so that a new frame is produced with the updated + // layer, otherwise this local root's visible content may not be up to date. + ancestor_render_widget_->ScheduleAnimation(); } embedded_layer_ = std::move(layer); }
diff --git a/content/test/gpu/gold_inexact_matching/base_parameter_optimizer.py b/content/test/gpu/gold_inexact_matching/base_parameter_optimizer.py index 4636363fd..50bee97 100644 --- a/content/test/gpu/gold_inexact_matching/base_parameter_optimizer.py +++ b/content/test/gpu/gold_inexact_matching/base_parameter_optimizer.py
@@ -48,6 +48,7 @@ self._working_dir = None self._expectations = None self._gold_url = 'https://%s-gold.skia.org' % args.gold_instance + self._pool = multiprocessing.Pool() # A map of strings, denoting a resolution or trace, to an iterable of # strings, denoting images that are that dimension or belong to that # trace. @@ -356,7 +357,6 @@ max_num_pixels = -1 max_max_delta = -1 - process_pool = multiprocessing.Pool() for resolution, digest_list in self._images.iteritems(): logging.debug('Resolution/trace: %s, digests: %s', resolution, digest_list) @@ -364,7 +364,7 @@ self._GenerateComparisonCmd(l, r, parameters) for (l, r) in itertools.combinations(digest_list, 2) ] - results = process_pool.map(RunCommandAndExtractData, cmds) + results = self._pool.map(RunCommandAndExtractData, cmds) for (success, num_pixels, max_delta) in results: num_attempts += 1 if success:
diff --git a/content/test/gpu/gold_inexact_matching/local_minima_parameter_optimizer.py b/content/test/gpu/gold_inexact_matching/local_minima_parameter_optimizer.py index a90acac1..350659b 100644 --- a/content/test/gpu/gold_inexact_matching/local_minima_parameter_optimizer.py +++ b/content/test/gpu/gold_inexact_matching/local_minima_parameter_optimizer.py
@@ -21,6 +21,21 @@ MIN_EDGE_THRESHOLD_WEIGHT = 0 MIN_MAX_DIFF_WEIGHT = MIN_DELTA_THRESHOLD_WEIGHT = 0 + def __init__(self, args, test_name): + super(LocalMinimaParameterOptimizer, self).__init__(args, test_name) + # These are (or will be) maps of ints to maps of ints to ints, i.e. a 2D + # array containing ints, just using maps instead of lists. They hold the + # most permissive value visited so far that resulted in a comparison failure + # for a particular parameter given the other two parameters. These are used + # to prune combinations we don't care about, similar to skipping + # combinations that produce a higher weight than our smallest. + # Delta -> Edge -> Max Diff + self._permissive_max_diff_map = {} + # Max Diff -> Edge -> Delta + self._permissive_delta_map = {} + # Max Diff -> Delta -> Edge + self._permissive_edge_map = {} + @classmethod def AddArguments(cls, parser): common_group, sobel_group, fuzzy_group = super( @@ -75,7 +90,8 @@ # Do a search, only considering adjacent parameters if: # 1. Their weight is less than or equal to the smallest found weight. # 2. They haven't been visited already. - # 3. The current parameters result in a successful comparison. + # 3. They are not guaranteed to fail based on previously tested parameters. + # 4. The current parameters result in a successful comparison. while len(to_visit): current_parameters = None if self._args.use_bfs: @@ -87,6 +103,9 @@ continue if current_parameters in visited_parameters: continue + if self._ParametersAreGuaranteedToFail(current_parameters): + visited_parameters.add(current_parameters) + continue visited_parameters.add(current_parameters) success, _, _ = self._RunComparisonForParameters(current_parameters) if success: @@ -101,11 +120,75 @@ weight, current_parameters) smallest_weight = weight smallest_parameters = [current_parameters] + else: + self._UpdateMostPermissiveFailedParameters(current_parameters) print 'Found %d parameter(s) with the smallest weight:' % len( smallest_parameters) for p in smallest_parameters: print p + def _ParametersAreGuaranteedToFail(self, parameters): + """Checks whether the given ParameterSet is guaranteed to fail. + + A ParameterSet is guaranteed to fail if we have already tried and failed + with a similar ParameterSet that was more permissive. Specifically, if we + have tried and failed with a ParameterSet with all but one parameters + matching, and the non-matching parameter was more permissive than the + current one. + + Args: + parameters: The ParameterSet instance to check. + + Returns: + True if |parameters| is guaranteed to fail based on previously tried + parameters, otherwise False. + """ + permissive_max_diff = self._permissive_max_diff_map.get( + parameters.delta_threshold, {}).get(parameters.edge_threshold, -1) + if parameters.max_diff < permissive_max_diff: + return True + + permissive_delta = self._permissive_delta_map.get( + parameters.max_diff, {}).get(parameters.edge_threshold, -1) + if parameters.delta_threshold < permissive_delta: + return True + + permissive_edge = self._permissive_edge_map.get( + parameters.max_diff, {}).get(parameters.delta_threshold, sys.maxsize) + if parameters.edge_threshold > permissive_edge: + return True + + return False + + def _UpdateMostPermissiveFailedParameters(self, parameters): + """Updates the array of most permissive failed parameters. + + This is used in conjunction with _ParametersAreGuaranteedToFail to prune + ParameterSets without having to actually test them. Values are updated if + |parameters| shares two parameters with a a previously failed ParameterSet, + but |parameters|' third parameter is more permissive. + + Args: + parameters: A ParameterSet to pull updated values from. + """ + permissive_max_diff = self._permissive_max_diff_map.setdefault( + parameters.delta_threshold, {}).get(parameters.edge_threshold, -1) + permissive_max_diff = max(permissive_max_diff, parameters.max_diff) + self._permissive_max_diff_map[parameters.delta_threshold][ + parameters.edge_threshold] = permissive_max_diff + + permissive_delta = self._permissive_delta_map.setdefault( + parameters.max_diff, {}).get(parameters.edge_threshold, -1) + permissive_delta = max(permissive_delta, parameters.delta_threshold) + self._permissive_delta_map[parameters.max_diff][ + parameters.edge_threshold] = permissive_delta + + permissive_edge = self._permissive_edge_map.setdefault( + parameters.max_diff, {}).get(parameters.delta_threshold, sys.maxsize) + permissive_edge = min(permissive_edge, parameters.edge_threshold) + self._permissive_edge_map[parameters.max_diff][ + parameters.delta_threshold] = permissive_edge + def _AdjacentParameters(self, starting_parameters): max_diff = starting_parameters.max_diff delta_threshold = starting_parameters.delta_threshold
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index d176615..b96af70 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -154,6 +154,12 @@ def DefaultPages(base_name): sw_compositing_args = ['--disable-gpu-compositing'] + # The optimizer script spat out pretty similar values for most MP4 tests, so + # combine into a single set of parameters. + general_mp4_algo = algo.SobelMatchingAlgorithm(max_different_pixels=56300, + pixel_delta_threshold=35, + edge_threshold=80) + return [ PixelTestPage('pixel_background_image.html', base_name + '_BackgroundImage', @@ -203,51 +209,60 @@ PixelTestPage('pixel_background.html', base_name + '_SolidColorBackground', test_rect=[500, 500, 100, 100]), - PixelTestPage('pixel_video_mp4.html', - base_name + '_Video_MP4', - test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + PixelTestPage( + 'pixel_video_mp4.html', + base_name + '_Video_MP4', + test_rect=[0, 0, 240, 135], + # Most images are actually very similar, but Pixel 2 + # tends to produce images with all colors shifted by a + # small amount. + matching_algorithm=general_mp4_algo), + # Surprisingly stable, does not appear to require inexact matching. PixelTestPage('pixel_video_mp4.html', base_name + '_Video_MP4_DXVA', browser_args=['--disable-features=D3D11VideoDecoder'], - test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + test_rect=[0, 0, 240, 135]), PixelTestPage('pixel_video_mp4_four_colors_aspect_4x3.html', base_name + '_Video_MP4_FourColors_Aspect_4x3', test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + matching_algorithm=algo.SobelMatchingAlgorithm( + max_different_pixels=41700, + pixel_delta_threshold=15, + edge_threshold=40)), PixelTestPage('pixel_video_mp4_four_colors_rot_90.html', base_name + '_Video_MP4_FourColors_Rot_90', test_rect=[0, 0, 270, 240], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + matching_algorithm=general_mp4_algo), PixelTestPage('pixel_video_mp4_four_colors_rot_180.html', base_name + '_Video_MP4_FourColors_Rot_180', test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + matching_algorithm=general_mp4_algo), PixelTestPage('pixel_video_mp4_four_colors_rot_270.html', base_name + '_Video_MP4_FourColors_Rot_270', test_rect=[0, 0, 270, 240], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + matching_algorithm=general_mp4_algo), PixelTestPage('pixel_video_mp4_rounded_corner.html', base_name + '_Video_MP4_Rounded_Corner', - test_rect=[0, 0, 240, 135]), + test_rect=[0, 0, 240, 135], + matching_algorithm=algo.SobelMatchingAlgorithm( + max_different_pixels=30500, + pixel_delta_threshold=15, + edge_threshold=70)), PixelTestPage('pixel_video_vp9.html', base_name + '_Video_VP9', test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + matching_algorithm=algo.SobelMatchingAlgorithm( + max_different_pixels=114000, + pixel_delta_threshold=30, + edge_threshold=20)), PixelTestPage('pixel_video_vp9.html', base_name + '_Video_VP9_DXVA', browser_args=['--disable-features=D3D11VideoDecoder'], test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + matching_algorithm=algo.SobelMatchingAlgorithm( + max_different_pixels=31100, + pixel_delta_threshold=30, + edge_threshold=250)), # The MP4 contains H.264 which is primarily hardware decoded on bots. PixelTestPage( @@ -255,8 +270,11 @@ '/media/test/data/four-colors.mp4', base_name + '_Video_Context_Loss_MP4', test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, + # Optimizer script spat out a value of 255 for the Sobel edge + # threshold, so use fuzzy for now since it's slightly more + # efficient. + matching_algorithm=algo.FuzzyMatchingAlgorithm( + max_different_pixels=31700, pixel_delta_threshold=20), expected_per_process_crashes={ CRASH_TYPE_GPU: 1, }), @@ -266,8 +284,10 @@ '?src=/media/test/data/four-colors-vp9.webm'), base_name + '_Video_Context_Loss_VP9', test_rect=[0, 0, 240, 135], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, + matching_algorithm=algo.SobelMatchingAlgorithm( + max_different_pixels=54400, + pixel_delta_threshold=30, + edge_threshold=250), expected_per_process_crashes={ CRASH_TYPE_GPU: 1, }), @@ -305,28 +325,20 @@ PixelTestPage('pixel_webgl_read_pixels_tab_switch.html', base_name + '_WebGLReadPixelsTabSwitch', test_rect=[0, 0, 100, 100], - optional_action='SwitchTabs', - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + optional_action='SwitchTabs'), PixelTestPage('pixel_webgl_read_pixels_tab_switch.html', base_name + '_WebGLReadPixelsTabSwitch_SoftwareCompositing', test_rect=[0, 0, 100, 100], browser_args=sw_compositing_args, - optional_action='SwitchTabs', - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + optional_action='SwitchTabs'), PixelTestPage('pixel_offscreen_canvas_ibrc_webgl_main.html', base_name + '_OffscreenCanvasIBRCWebGLMain', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunOffscreenCanvasIBRCWebGLTest'), PixelTestPage('pixel_offscreen_canvas_ibrc_webgl_worker.html', base_name + '_OffscreenCanvasIBRCWebGLWorker', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunOffscreenCanvasIBRCWebGLTest'), ] @@ -340,15 +352,11 @@ PixelTestPage('pixel_background.html', base_name + '_GpuRasterization_BlueBox', test_rect=[0, 0, 220, 220], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), PixelTestPage('concave_paths.html', base_name + '_GpuRasterization_ConcavePaths', test_rect=[0, 0, 100, 100], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), PixelTestPage('pixel_precision_rounded_corner.html', base_name + '_PrecisionRoundedCorner', test_rect=[0, 0, 400, 400], @@ -401,9 +409,7 @@ PixelTestPage('pixel_offscreenCanvas_webgl_paint_after_resize.html', base_name + '_OffscreenCanvasWebGLPaintAfterResize', test_rect=[0, 0, 200, 200], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), PixelTestPage('pixel_offscreenCanvas_transferToImageBitmap_main.html', base_name + '_OffscreenCanvasTransferToImageBitmap', test_rect=[0, 0, 300, 300], @@ -488,9 +494,7 @@ PixelTestPage('pixel_canvas_low_latency_webgl.html', base_name + '_CanvasLowLatencyWebGL', test_rect=[0, 0, 200, 200], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), ] @staticmethod @@ -506,15 +510,11 @@ PixelTestPage('pixel_canvas_low_latency_webgl.html', base_name + '_CanvasLowLatencyWebGLSwapChain', test_rect=[0, 0, 200, 200], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), PixelTestPage('pixel_canvas_low_latency_webgl_alpha_false.html', base_name + '_CanvasLowLatencyWebGLSwapChainAlphaFalse', test_rect=[0, 0, 200, 200], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), ] # Only add these tests on platforms where SwiftShader is enabled. @@ -539,9 +539,7 @@ PixelTestPage('pixel_repeated_webgl_to_2d.html', base_name + '_RepeatedWebGLTo2D' + suffix, test_rect=[0, 0, 256, 256], - browser_args=browser_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=browser_args), ] # Test rendering where GPU process is blocked. @@ -634,9 +632,7 @@ PixelTestPage('pixel_webgl_premultiplied_alpha_false.html', base_name + '_WebGL_PremultipliedAlpha_False_NoOverlays', test_rect=[0, 0, 150, 150], - browser_args=no_overlays_args, - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO), + browser_args=no_overlays_args), ] # Pages that should be run only on dual-GPU MacBook Pros (at the @@ -647,34 +643,24 @@ PixelTestPage('pixel_webgl_high_to_low_power.html', base_name + '_WebGLHighToLowPower', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunTestWithHighPerformanceTab'), PixelTestPage('pixel_webgl_low_to_high_power.html', base_name + '_WebGLLowToHighPower', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunLowToHighPowerTest'), PixelTestPage('pixel_webgl_low_to_high_power_alpha_false.html', base_name + '_WebGLLowToHighPowerAlphaFalse', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunLowToHighPowerTest'), PixelTestPage( 'pixel_offscreen_canvas_ibrc_webgl_main.html', base_name + '_OffscreenCanvasIBRCWebGLHighPerfMain', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunOffscreenCanvasIBRCWebGLHighPerfTest'), PixelTestPage( 'pixel_offscreen_canvas_ibrc_webgl_worker.html', base_name + '_OffscreenCanvasIBRCWebGLHighPerfWorker', test_rect=[0, 0, 300, 300], - grace_period_end=datetime.date(2020, 6, 22), - matching_algorithm=VERY_PERMISSIVE_SOBEL_ALGO, optional_action='RunOffscreenCanvasIBRCWebGLHighPerfTest'), ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 3ff53bea..2318301 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -304,6 +304,7 @@ crbug.com/1085222 [ win10 intel-0x5912 d3d11 ] deqp/functional/gles3/shaderoperator/binary_operator_01.html [ RetryOnFailure ] crbug.com/1085222 [ win10 intel-0x5912 d3d11 ] deqp/functional/gles3/shaderoperator/unary_operator_01.html [ RetryOnFailure ] crbug.com/1085222 [ win10 intel-0x5912 d3d11 ] deqp/functional/gles3/shaderoperator/unary_operator_02.html [ RetryOnFailure ] +crbug.com/1087993 [ win10 intel-0x5912 d3d11 ] conformance2/textures/image_data/tex-2d-rgb8ui-rgb_integer-unsigned_byte.html [ RetryOnFailure ] crbug.com/1087993 [ win10 intel-0x5912 d3d11 ] conformance2/textures/image_data/tex-2d-srgb8_alpha8-rgba-unsigned_byte.html [ RetryOnFailure ] ####################
diff --git a/device/fido/fido_device_authenticator.cc b/device/fido/fido_device_authenticator.cc index e55a322..cf66389 100644 --- a/device/fido/fido_device_authenticator.cc +++ b/device/fido/fido_device_authenticator.cc
@@ -23,6 +23,41 @@ namespace device { +namespace { + +// Helper method for determining correct bio enrollment version. +BioEnrollmentRequest::Version GetBioEnrollmentRequestVersion( + const AuthenticatorSupportedOptions& options) { + // TODO(crbug.com/1087419): return default version for authenticators that + // support it regardless of preview availability once we implement + // getPinUvAuthTokenUsingPinWithPermissions. + DCHECK(options.bio_enrollment_availability_preview != + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported || + options.bio_enrollment_availability != + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported); + return options.bio_enrollment_availability_preview != + AuthenticatorSupportedOptions::BioEnrollmentAvailability:: + kNotSupported + ? BioEnrollmentRequest::kPreview + : BioEnrollmentRequest::kDefault; +} + +CredentialManagementRequest::Version GetCredentialManagementRequestVersion( + const AuthenticatorSupportedOptions& options) { + // TODO(crbug.com/1087419): return default version for authenticators that + // support it regardless of preview availability once we implement + // getPinUvAuthTokenUsingPinWithPermissions. + DCHECK(options.supports_credential_management_preview || + options.supports_credential_management); + return options.supports_credential_management_preview + ? CredentialManagementRequest::kPreview + : CredentialManagementRequest::kDefault; +} + +} // namespace + FidoDeviceAuthenticator::FidoDeviceAuthenticator( std::unique_ptr<FidoDevice> device) : device_(std::move(device)) {} @@ -326,10 +361,7 @@ RunOperation<CredentialManagementRequest, CredentialsMetadataResponse>( CredentialManagementRequest::ForGetCredsMetadata( - Options()->supports_credential_management - ? CredentialManagementRequest::kDefault - : CredentialManagementRequest::kPreview, - pin_token), + GetCredentialManagementRequestVersion(*Options()), pin_token), std::move(callback), base::BindOnce(&CredentialsMetadataResponse::Parse)); } @@ -359,10 +391,7 @@ state.callback = std::move(callback); RunOperation<CredentialManagementRequest, EnumerateRPsResponse>( CredentialManagementRequest::ForEnumerateRPsBegin( - Options()->supports_credential_management - ? CredentialManagementRequest::kDefault - : CredentialManagementRequest::kPreview, - pin_token), + GetCredentialManagementRequestVersion(*Options()), pin_token), base::BindOnce(&FidoDeviceAuthenticator::OnEnumerateRPsDone, weak_factory_.GetWeakPtr(), std::move(state)), base::BindOnce(&EnumerateRPsResponse::Parse, /*expect_rp_count=*/true), @@ -459,10 +488,8 @@ state.responses.emplace_back(std::move(*response->rp)); auto request = CredentialManagementRequest::ForEnumerateCredentialsBegin( - Options()->supports_credential_management - ? CredentialManagementRequest::kDefault - : CredentialManagementRequest::kPreview, - state.pin_token, std::move(*response->rp_id_hash)); + GetCredentialManagementRequestVersion(*Options()), state.pin_token, + std::move(*response->rp_id_hash)); RunOperation<CredentialManagementRequest, EnumerateCredentialsResponse>( std::move(request), base::BindOnce(&FidoDeviceAuthenticator::OnEnumerateCredentialsDone, @@ -490,9 +517,7 @@ state.current_rp_credential_count) { RunOperation<CredentialManagementRequest, EnumerateCredentialsResponse>( CredentialManagementRequest::ForEnumerateCredentialsGetNext( - Options()->supports_credential_management - ? CredentialManagementRequest::kDefault - : CredentialManagementRequest::kPreview), + GetCredentialManagementRequestVersion(*Options())), base::BindOnce(&FidoDeviceAuthenticator::OnEnumerateCredentialsDone, weak_factory_.GetWeakPtr(), std::move(state)), base::BindOnce(&EnumerateCredentialsResponse::Parse, @@ -504,9 +529,7 @@ if (state.responses.size() < state.rp_count) { RunOperation<CredentialManagementRequest, EnumerateRPsResponse>( CredentialManagementRequest::ForEnumerateRPsGetNext( - Options()->supports_credential_management - ? CredentialManagementRequest::kDefault - : CredentialManagementRequest::kPreview), + GetCredentialManagementRequestVersion(*Options())), base::BindOnce(&FidoDeviceAuthenticator::OnEnumerateRPsDone, weak_factory_.GetWeakPtr(), std::move(state)), base::BindOnce(&EnumerateRPsResponse::Parse, @@ -529,24 +552,12 @@ RunOperation<CredentialManagementRequest, DeleteCredentialResponse>( CredentialManagementRequest::ForDeleteCredential( - Options()->supports_credential_management - ? CredentialManagementRequest::kDefault - : CredentialManagementRequest::kPreview, - pin_token, credential_id), + GetCredentialManagementRequestVersion(*Options()), pin_token, + credential_id), std::move(callback), base::BindOnce(&DeleteCredentialResponse::Parse), /*string_fixup_predicate=*/nullptr); } -// Helper method for determining correct bio enrollment version. -static BioEnrollmentRequest::Version GetBioEnrollmentRequestVersion( - const AuthenticatorSupportedOptions& options) { - return options.bio_enrollment_availability != - AuthenticatorSupportedOptions::BioEnrollmentAvailability:: - kNotSupported - ? BioEnrollmentRequest::kDefault - : BioEnrollmentRequest::kPreview; -} - void FidoDeviceAuthenticator::GetModality(BioEnrollmentCallback callback) { RunOperation<BioEnrollmentRequest, BioEnrollmentResponse>( BioEnrollmentRequest::ForGetModality(
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc index 803ecd54..5ecb96f 100644 --- a/device/fido/virtual_ctap2_device.cc +++ b/device/fido/virtual_ctap2_device.cc
@@ -432,6 +432,7 @@ if (config.credential_management_support) { options_updated = true; options.supports_credential_management = true; + options.supports_credential_management_preview = true; } if (config.bio_enrollment_support) { @@ -569,6 +570,7 @@ break; } case CtapRequestCommand::kAuthenticatorCredentialManagement: + case CtapRequestCommand::kAuthenticatorCredentialManagementPreview: response_code = OnCredentialManagement(request_bytes, &response_data); break; case CtapRequestCommand::kAuthenticatorBioEnrollment:
diff --git a/docs/ui/learn/bestpractices/layout.md b/docs/ui/learn/bestpractices/layout.md new file mode 100644 index 0000000..5740c73 --- /dev/null +++ b/docs/ui/learn/bestpractices/layout.md
@@ -0,0 +1,1350 @@ +# Best practice: layout + +The most important principles when working with Views layout are abstraction +and encapsulation. The goal of the guidance here is to split the broad work of +"layout" into many discrete pieces, each of which can be easily understood, +tested, and changed in isolation. Compliant code should be more readable, +performant, and maintainable; more adaptable to future modifications; and more +stylistically consistent with other UI elements both now and in the future. + +[TOC] + +## Express layout values logically + +Both in mocks and code, **layout values should be described in functional terms +that conform to the relevant specs** (particularly the +[Material Refresh][] and older [Harmony][] specs). Rather than a mock saying +a dialog title is "15 pt high", it should say it is the "Title 1" or +"DIALOG\_TITLE" style; two non-interacting controls on the same line should not +be separated by "16 dip" but by [`DISTANCE_UNRELATED_CONTROL_HORIZONTAL`][]. +Designers and engineers can reference a [dictionary][] to agree on common +terminology. Don't simply back-figure the constant to use based on what +produces the same value as the mock, as future design system changes will +cause subtle and confusing bugs. Similarly, don't hardcode designer-provided +values that aren't currently present in Chrome, as the semantics of such +one-off values are unclear and will cause maintenance problems. +Work with the Toolkit and UX teams to modify the design and overall spec so +the desired results can be achieved in a centralized way. + +Note: the concept in this section is general, but the linked specs are +**Googlers Only**. + +[Material Refresh]: https://docs.google.com/presentation/d/1EO7TOpIMJ7QHjaTVw9St-q6naKwtXX2TwzMirG5EsKY/edit#slide=id.g3232c09376_6_794 +[Harmony]: https://folio.googleplex.com/chrome-ux-specs-and-sources/Chrome%20browser%20%28MD%29/Secondary%20UI%20Previews%20and%20specs%20%28exports%29/Spec +[`DISTANCE_UNRELATED_CONTROL_HORIZONTAL`]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/chrome_layout_provider.h;l=56;drc=ec62c9ac3ef71a7014e27c5d2cf98917a89e3524 +[dictionary]: http://go/DesktopDictionary + +## Obtain layout values from provider objects + +Once layout styles and values are expressed functionally, **the exact values +should be obtained from relevant provider objects, not computed directly.** +Code should not have any magic numbers for sizes, positions, elevations, and +the like; this includes transformations like scaling values up or down by a +fraction, or tweaking a provided value by a few DIPs. The most commonly used +provider object is the [`LayoutProvider`][] (or its `chrome`/-side extension, +[`ChromeLayoutProvider`][]); `View`s can obtain the global instance via a +relevant [`Get()`][] method and ask it for relevant [distances][], [insets][], +[corner radii][], [shadow elevations][], and the like. For text-setting +controls like [`Label`][], the [`TypographyProvider`][] (or its +`chrome`/-side extension, [`ChromeTypographyProvider`]), +usually accessed via [global helper functions][], can provide appropriate +[fonts][], [colors][], and [line heights][]. Most `View`s should not use these +directly, but use `Label` and other such controls, providing the appropriate +[context][] and [style][]. + +[`LayoutProvider`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_provider.h;l=129;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 +[`ChromeLayoutProvider`]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/chrome_layout_provider.h;drc=ec62c9ac3ef71a7014e27c5d2cf98917a89e3524;l=76 +[`Get()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_provider.h;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38;l=135 +[distances]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_provider.h;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38;l=148 +[insets]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_provider.h;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38;l=144 +[corner radii]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_provider.h;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38;l=168 +[shadow elevations]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_provider.h;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38;l=172 +[`Label`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/controls/label.h;l=30;drc=59135b4042aa469752899e8e4bf2a0a81d3d320c +[`TypographyProvider`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography_provider.h;l=22;drc=b5e29e075e814ed41e6727c281b69f797d8a1e10 +[`ChromeTypographyProvider`]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/chrome_typography_provider.h;l=13;drc=a7ee000c95842e2dce6397ca36926924f4cb322b +[global helper functions]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography.h;l=109;drc=8f7db479018a99e5906876954de93ae6d23bee58 +[fonts]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography_provider.h;l=28;drc=b5e29e075e814ed41e6727c281b69f797d8a1e10 +[colors]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography_provider.h;l=32;drc=b5e29e075e814ed41e6727c281b69f797d8a1e10 +[line heights]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography_provider.h;l=37;drc=b5e29e075e814ed41e6727c281b69f797d8a1e10 +[context]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography.h;l=23;drc=8f7db479018a99e5906876954de93ae6d23bee58 +[style]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/style/typography.h;l=67;drc=8f7db479018a99e5906876954de93ae6d23bee58 + +|||---||| + +##### + +**Avoid** + +[Current code][1] uses file scoped hard-coded padding values for its layout +constants. + +[1]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/subtle_notification_view.cc;l=142;drc=787d0aacc071674dc83f6059072d15f8cfffbf84 + +##### + +**Best practice** + +A better approach would be to use layout constants sourced from the +[`ChromeLayoutProvider`][]. + +|||---||| + +|||---||| + +##### + +``` cpp +namespace { +// Space between the site info label. +const int kMiddlePaddingPx = 30; + +const int kOuterPaddingHorizPx = 40; +const int kOuterPaddingVertPx = 8; +} // namespace + +SubtleNotificationView::SubtleNotificationView() + : instruction_view_(nullptr) { + ... + instruction_view_ = + new InstructionView(base::string16()); + + int outer_padding_horiz = kOuterPaddingHorizPx; + int outer_padding_vert = kOuterPaddingVertPx; + AddChildView(instruction_view_); + + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets(outer_padding_vert, + outer_padding_horiz), + kMiddlePaddingPx)); +} +``` + +##### + +``` cpp + + + + + + + + +SubtleNotificationView::SubtleNotificationView() + : instruction_view_(nullptr) { + ... + AddChildView(std::make_unique<InstructionView>( + base::string16())); + + const gfx::Insets kDialogInsets = + ChromeLayoutProvider::Get()->GetInsetsMetric( + views::INSETS_DIALOG); + const int kHorizontalPadding = + ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_RELATED_LABEL_HORIZONTAL); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + kDialogInsets, kHorizontalPadding)); +} +``` + +|||---||| + + +## Use hierarchy liberally + +While not a layout-specific tactic, it simplifies many layout issues +**to break a high-level UI construct into a hierarchy of `View`s**, +with as many levels as necessary to make each `View` as simple as possible. +In such hierarchies, most non-leaf `View`s will be nameless "containers" that +simply size or group their immediate children, perhaps with padding between +them or a margin around the outside. Each such `View` is easy to lay out, +and you can later combine or factor out pieces of the hierarchy as appropriate, +including adding helpers for common Material Design idioms to the core toolkit. + + +## Use LayoutManagers + +**Avoid overriding [`Layout()`][] to programmatically lay out children.** +In nearly all cases, the built-in [`LayoutManager`][]s can achieve the desired +layout, and do so in a declarative rather than imperative fashion. The +resulting code is often simpler and easier to understand. Writing a [bespoke +`LayoutManager`][] is also possible, but less common. + +[`Layout()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.h;l=730;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 +[`LayoutManager`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/layout_manager.h;l=33;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 +[bespoke `LayoutManager`]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/try_chrome_dialog_win/button_layout.h;l=30;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 + +|||---||| + +##### + +**Avoid** + +The following old code used Layout() to have its label text fill the dialog. + +##### + +**Best practice** + +[Current code][2] uses a [FillLayout][] to achieve the same result. + +[2]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/relaunch_notification/relaunch_required_dialog_view.cc;l=91;drc=1ec33e7c19e2d63b3f918df115c12f77f419645b +[FillLayout]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/fill_layout.h + +|||---||| + +|||---||| + +##### + +``` cpp +int RelaunchRequiredDialogView::GetHeightForWidth( + int width) const { + const gfx::Insets insets = GetInsets(); + return body_label_->GetHeightForWidth( + width - insets.width()) + insets.height(); +} + +void RelaunchRequiredDialogView::Layout() { + body_label_->SetBoundsRect(GetContentsBounds()); +} +``` + +##### + +``` cpp +RelaunchRequiredDialogView::RelaunchRequiredDialogView( + base::Time deadline, + base::RepeatingClosure on_accept) + : ...{ + SetLayoutManager( + std::make_unique<views::FillLayout>()); + ... +} + + +``` + +|||---||| + + +## Prefer intrinsic constraints to extrinsic computation + +Where possible, **express the desired outcome of layout in terms of intrinsic +constraints for each `View`,** instead of trying to conditionally compute +the desired output metrics. For example, using a [`ClassProperty`][] +to set each child's [margins][] is less error-prone than trying to +conditionally add padding `View`s between children. When coupled with +[margin collapsing][] and [internal padding][], it's possible to do things +like use [different padding amounts between different children][] +or visually align elements without manually computing offsets. +Such manual computation is prone to bugs if someone changes a size, padding +value, or child order in one place without also updating related computations +elsewhere. + +[`ClassProperty`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/base/class_property.h;l=55;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 +[margins]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view_class_properties.h;l=30;drc=1449b8c60358c4cdea1722e4c1e8079bd1b5f306 +[margin collapsing]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/flex_layout.h;l=87;drc=62bf27aca5418212ceadd8daf9188d2aa437bfcc +[internal padding]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view_class_properties.h;l=40;drc=1449b8c60358c4cdea1722e4c1e8079bd1b5f306 +[different padding amounts between different children]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/toolbar/toolbar_view.cc;l=974;drc=34a8c4215229379ced3586125399c7ad3c65b87f + +|||---||| + +##### + +**Avoid** + +The following is old code that calculated bubble padding through calculations +involving the control insets. + +##### + +**Best practice** + +[Current code][3] uses a combination of margin and padding on the +ColorPickerView to ensure proper alignment. + +[3]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/tabs/tab_group_editor_bubble_view.cc;l=89;drc=542c4c6ac89bc665807351d3fb4aca5ebddc82f8 + +|||---||| + +|||---||| + +##### + +``` cpp +TabGroupEditorBubbleView::TabGroupEditorBubbleView( + const Browser* browser, + const tab_groups::TabGroupId& group, + TabGroupHeader* anchor_view, + base::Optional<gfx::Rect> anchor_rect, + bool stop_context_menu_propagation) + : ... { + + ... + const auto* layout_provider = + ChromeLayoutProvider::Get(); + const int horizontal_spacing = + layout_provider->GetDistanceMetric( + views::DISTANCE_RELATED_CONTROL_HORIZONTAL); + const int vertical_menu_spacing = + layout_provider->GetDistanceMetric( + views::DISTANCE_RELATED_CONTROL_VERTICAL); + + // The vertical spacing for the non menu items within + // the editor bubble. + const int vertical_dialog_content_spacing = 16; + + + + + + + + + + + views::View* group_modifier_container = + AddChildView(std::make_unique<views::View>()); + + gfx::Insets color_element_insets = + ChromeLayoutProvider::Get()->GetInsetsMetric( + views::INSETS_VECTOR_IMAGE_BUTTON); + group_modifier_container->SetBorder( + views::CreateEmptyBorder( + gfx::Insets(vertical_dialog_content_spacing, + horizontal_spacing - + color_element_insets.left(), + vertical_dialog_content_spacing, + horizontal_spacing - + color_element_insets.right()))); + ... + // Add the text field for editing the title. + views::View* title_field_container = + group_modifier_container->AddChildView( + std::make_unique<views::View>()); + title_field_container->SetBorder( + views::CreateEmptyBorder(gfx::Insets( + 0, color_element_insets.left(), + vertical_dialog_content_spacing, + color_element_insets.right())) + ... + color_selector_ = + group_modifier_container->AddChildView( + std::make_unique<ColorPickerView>( + colors_, background_color(), initial_color, + base::Bind( + &TabGroupEditorBubbleView::UpdateGroup, + base::Unretained(this)))); + ... +} + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +##### + +``` cpp +TabGroupEditorBubbleView::TabGroupEditorBubbleView( + const Browser* browser, + const tab_groups::TabGroupId& group, + views::View* anchor_view, + base::Optional<gfx::Rect> anchor_rect, + TabGroupHeader* header_view, + bool stop_context_menu_propagation) + : ... { + ... + const auto* layout_provider = + ChromeLayoutProvider::Get(); + const int horizontal_spacing = + layout_provider->GetDistanceMetric( + views::DISTANCE_RELATED_CONTROL_HORIZONTAL); + const int vertical_spacing = + layout_provider->GetDistanceMetric( + views::DISTANCE_RELATED_CONTROL_VERTICAL); + + // The padding of the editing controls is adaptive, + // to improve the hit target size and screen real + // estate usage on touch devices. + const int group_modifier_vertical_spacing = + ui::TouchUiController::Get()->touch_ui() ? + vertical_spacing / 2 : vertical_spacing; + const gfx::Insets control_insets = + ui::TouchUiController::Get()->touch_ui() + ? gfx::Insets(5 * vertical_spacing / 4, + horizontal_spacing) + : gfx::Insets(vertical_spacing, + horizontal_spacing); + + views::View* group_modifier_container = + AddChildView(std::make_unique<views::View>()); + group_modifier_container->SetBorder( + views::CreateEmptyBorder(gfx::Insets( + group_modifier_vertical_spacing, 0))); + + views::FlexLayout* group_modifier_container_layout = + group_modifier_container->SetLayoutManager( + std::make_unique<views::FlexLayout>()); + group_modifier_container_layout + ->SetOrientation( + views::LayoutOrientation::kVertical) + .SetIgnoreDefaultMainAxisMargins(true); + + + // Add the text field for editing the title. + views::View* title_field_container = + group_modifier_container->AddChildView( + std::make_unique<views::View>()); + title_field_container->SetBorder( + views::CreateEmptyBorder( + control_insets.top(), control_insets.left(), + group_modifier_vertical_spacing, + control_insets.right())); + + ... + const tab_groups::TabGroupColorId initial_color_id = + InitColorSet(); + color_selector_ = + group_modifier_container->AddChildView( + std::make_unique<ColorPickerView>( + this, colors_, initial_color_id, + base::Bind( + &TabGroupEditorBubbleView::UpdateGroup, + base::Unretained(this)))); + color_selector_->SetProperty( + views::kMarginsKey, + gfx::Insets(0, control_insets.left(), 0, + control_insets.right())); + ... +} + +ColorPickerView::ColorPickerView( + const views::BubbleDialogDelegateView* bubble_view, + const TabGroupEditorBubbleView::Colors& colors, + tab_groups::TabGroupColorId initial_color_id, + ColorSelectedCallback callback) + : callback_(std::move(callback)) { + ... + // Set the internal padding to be equal to the + // horizontal insets of a color picker element, + // since that is the amount by which the color + // picker's margins should be adjusted to make it + // visually align with other controls. + gfx::Insets child_insets = elements_[0]->GetInsets(); + SetProperty(views::kInternalPaddingKey, + gfx::Insets(0, child_insets.left(), 0, + child_insets.right())); +} +``` + +|||---||| + +## Use GridLayout with caution + +[`GridLayout`][] is a `LayoutManager` used for tabular layouts. Much like +table-based layout in HTML, it can achieve almost any desired effect, and in +some scenarios (e.g. creating an actual table) is the best tool. Used +indiscriminately, it can be cryptic, verbose, and error-prone. Accordingly, +**use `GridLayout` only when creating a true grid, not simply for selective +horizontal and vertical alignment.** For simple layouts, [`BoxLayout`][] and +[`FlexLayout`][] are better choices; for more complex layouts, representing +sections or groups hierarchically may result in simpler inner layouts that +can be nested within an overall layout. + +[`GridLayout`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/grid_layout.h;l=79;drc=8cab3382ac9b70b7ecfe29ae03b1b7ee8f4e01fa +[`BoxLayout`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/box_layout.h;l=28;drc=5b9e43d976aca377588875fc59c5348ede02a8b5 +[`FlexLayout`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/layout/flex_layout.h;l=73;drc=62bf27aca5418212ceadd8daf9188d2aa437bfcc + +|||---||| + +##### + +**Avoid** + +The following old code uses a [`GridLayout`][] to create a HoverButton with +a stacked title and subtitle flanked on by views on both sides. + +##### + +**Best practice** + +[Current code][4] uses [`FlexLayout`][] to achieve the desired result, resulting +in clearer code. + +[4]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/hover_button.cc;l=106;drc=888af74006ea1c4ee9907d18c8df2a7ca424eab9 + +|||---||| + +|||---||| + +##### + +``` cpp +// Used to create the following layout +// +-----------+---------------------+----------------+ +// | icon_view | title | secondary_view | +// +-----------+---------------------+----------------+ +// | | subtitle | | +// +-----------+---------------------+----------------+ +HoverButton::HoverButton( + views::ButtonListener* button_listener, + std::unique_ptr<views::View> icon_view, + const base::string16& title, + const base::string16& subtitle, + std::unique_ptr<views::View> secondary_view, + bool resize_row_for_secondary_view, + bool secondary_view_can_process_events) { + ... + views::GridLayout* grid_layout = + SetLayoutManager( + std::make_unique<views::GridLayout>()); + ... + constexpr int kColumnSetId = 0; + views::ColumnSet* columns = + grid_layout->AddColumnSet(kColumnSetId); + columns->AddColumn( + views::GridLayout::CENTER, + views::GridLayout::CENTER, + views::GridLayout::kFixedSize, + views::GridLayout::USE_PREF, 0, 0); + columns->AddPaddingColumn( + views::GridLayout::kFixedSize, + icon_label_spacing); + columns->AddColumn( + views::GridLayout::FILL, + views::GridLayout::FILL, + 1.0, views::GridLayout::USE_PREF, 0, 0); + ... + grid_layout->StartRow( + views::GridLayout::kFixedSize, kColumnSetId, + row_height); + icon_view_ = grid_layout->AddView( + std::move(icon_view), 1, num_labels); + ... + auto title_wrapper = + std::make_unique<SingleLineStyledLabelWrapper>( + title); + title_ = title_wrapper->label(); + grid_layout->AddView(std::move(title_wrapper)); + + if (secondary_view) { + columns->AddColumn( + views::GridLayout::CENTER, + views::GridLayout::CENTER, + views::GridLayout::kFixedSize, + views::GridLayout::USE_PREF, 0, 0); + ... + secondary_view_ = + grid_layout->AddView( + std::move(secondary_view), 1, num_labels); + ... + } + if (!subtitle.empty()) { + grid_layout->StartRow( + views::GridLayout::kFixedSize, kColumnSetId, + row_height); + auto subtitle_label = + std::make_unique<views::Label>( + subtitle, views::style::CONTEXT_BUTTON, + views::style::STYLE_SECONDARY); + ... + grid_layout->SkipColumns(1); + subtitle_ = + grid_layout->AddView(std::move(subtitle_label)); + } + ... +} +``` + +##### + +``` cpp +// Used to create the following layout +// +-----------+---------------------+----------------+ +// | | title | | +// | icon_view |---------------------| secondary_view | +// | | subtitle | | +// +-----------+---------------------+----------------+ +HoverButton::HoverButton( + views::ButtonListener* button_listener, + std::unique_ptr<views::View> icon_view, + const base::string16& title, + const base::string16& subtitle, + std::unique_ptr<views::View> secondary_view, + bool resize_row_for_secondary_view, + bool secondary_view_can_process_events) { + ... + SetLayoutManager( + std::make_unique<views::FlexLayout>()) + ->SetCrossAxisAlignment( + views::LayoutAlignment::kCenter) + .SetChildViewIgnoredByLayout( + ink_drop_container(), true); + ... + icon_view_ = + AddChildView(std::make_unique<IconWrapper>( + std::move(icon_view), vertical_spacing)) + ->icon(); + + // |label_wrapper| will hold both the title and + // subtitle if it exists. + auto label_wrapper = std::make_unique<views::View>(); + title_ = label_wrapper->AddChildView( + std::make_unique<views::StyledLabel>( + title, nullptr)); + + if (!subtitle.empty()) { + auto subtitle_label = + std::make_unique<views::Label>( + subtitle, views::style::CONTEXT_BUTTON, + views::style::STYLE_SECONDARY); + ... + subtitle_ = label_wrapper->AddChildView( + std::move(subtitle_label)); + } + + label_wrapper->SetLayoutManager( + std::make_unique<views::FlexLayout>()) + ->SetOrientation( + views::LayoutOrientation::kVertical) + .SetMainAxisAlignment( + views::LayoutAlignment::kCenter); + label_wrapper->SetProperty( + views::kFlexBehaviorKey, + views::FlexSpecification( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded)); + label_wrapper->SetProperty( + views::kMarginsKey, + gfx::Insets(vertical_spacing, 0)); + label_wrapper_ = + AddChildView(std::move(label_wrapper)); + ... + + if (secondary_view) { + ... + secondary_view->SetProperty( + views::kMarginsKey, + gfx::Insets(secondary_spacing, + icon_label_spacing, + secondary_spacing, 0)); + secondary_view_ = + AddChildView(std::move(secondary_view)); + } + ... +} +``` + +|||---||| + +## Compute preferred/minimum sizes recursively from children + +**Avoid hardcoding preferred or minimum sizes,** including via metrics like +[`DISTANCE_BUBBLE_PREFERRED_WIDTH`][]. +In many cases, `LayoutManager`s will provide reasonable values for these, +and common codepaths like [`BubbleFrameView::GetFrameWidthForClientWidth()`][] +can help ensure that the returned values are [conformed to spec][]. +When a `View` does need to calculate these manually, it should do so based on +the corresponding values returned by its children, not by returning specific +numbers (e.g. dialog preferred size is 300 by 150). In particular, assuming +fonts will be in a certain size, or that a given fixed area is sufficient to +display all necessary information, can cause hard-to-find localization and +accessibility bugs for users with verbose languages or unusually large fonts. + +[`DISTANCE_BUBBLE_PREFERRED_WIDTH`]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/chrome_layout_provider.h;l=68;drc=ec62c9ac3ef71a7014e27c5d2cf98917a89e3524 +[`BubbleFrameView::GetFrameWidthForClientWidth()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/bubble/bubble_frame_view.cc;l=688;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 +[conformed to spec]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/bubble/bubble_frame_view.cc;l=698;drc=f5df5da5753795298349b2dd6325e2c5e6e13e38 + +|||---||| + +##### + +**Avoid** + +Current code overloads CalculatePreferredSize() in the dialog view. + +##### + +**Best practice** + +A better approach would be to omit the overload completely and let leaf views +size the dialog appropriately, relying on the minimum size fallbacks +if necessary. + +|||---||| + +|||---||| + +##### + +``` cpp +... +gfx::Size +CastDialogView::CalculatePreferredSize() const { + const int width = + ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_BUBBLE_PREFERRED_WIDTH); + return gfx::Size(width, GetHeightForWidth(width)); +} +``` + +##### + +``` cpp +... +``` + +|||---||| + + +## Handle events directly, not via Layout() + +In addition to using `LayoutManager`s in place of manual layout, +**avoid overriding `Layout()` to perform non-layout actions.** For example, +instead of updating properties tied to a `View`'s size in `Layout()`, +do so in [`OnBoundsChanged()`][]; +when the `View` in question is a child, make the child a `View` subclass +with an `OnBoundsChanged()` override instead of having the parent both lay +the child out and update its properties. Modify the +[hit-testing and event-handling functions][] directly instead of laying out +invisible `View`s to intercept events. Toggle child visibility directly in +response to external events rather than calculating it inside `Layout()`. + +[`OnBoundsChanged()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.h;l=1377;drc=34a8c4215229379ced3586125399c7ad3c65b87f +[hit-testing and event-handling functions]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.h;l=919;drc=34a8c4215229379ced3586125399c7ad3c65b87f + +|||---||| + +##### + +**Avoid** + +Old code updated hit testing and button properties in the Layout() method. + +##### + +**Best practice** + +Current code wraps the buttons in a file scoped class with an +OnBoundsChanged() method and modifies the hit testing functions directly to +achieve the same result. + +|||---||| + +|||---||| + +##### + +``` cpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +FindBarView::FindBarView(FindBarHost* host) + : find_bar_host_(host) { + auto find_text = std::make_unique<views::Textfield>(); + find_text_ = AddChildView(std::move(find_text)); + ... + auto find_previous_button = + views::CreateVectorImageButton(this); + find_previous_button_ = + AddChildView(std::move(find_previous_button)); + ... + auto find_next_button = + views::CreateVectorImageButton(this); + find_next_button_ = + AddChildView(std::move(find_next_button)); + ... + auto close_button = + views::CreateVectorImageButton(this); + close_button_ = + AddChildView(std::move(close_button)); +} + +void FindBarView::Layout() { + views::View::Layout(); + // The focus forwarder view is a hidden view that + // should cover the area between the find text box + // and the find button so that when the user clicks + // in that area we focus on the find text box. + const int find_text_edge = + find_text_->x() + find_text_->width(); + focus_forwarder_view_->SetBounds( + find_text_edge, find_previous_button_->y(), + find_previous_button_->x() - find_text_edge, + find_previous_button_->height()); + + for (auto* button : + {find_previous_button_, find_next_button_, + close_button_}) { + constexpr int kCircleDiameterDp = 24; + auto highlight_path = std::make_unique<SkPath>(); + // Use a centered circular shape for inkdrops and + // focus rings. + gfx::Rect circle_rect(button->GetLocalBounds()); + circle_rect.ClampToCenteredSize( + gfx::Size(kCircleDiameterDp, + kCircleDiameterDp)); + highlight_path->addOval( + gfx::RectToSkRect(circle_rect)); + button->SetProperty(views::kHighlightPathKey, + highlight_path.release()); + } +} +``` + +##### + +``` cpp +// An ImageButton that has a centered circular +// highlight. +class FindBarView::FindBarButton + : public views::ImageButton { + public: + using ImageButton::ImageButton; + protected: + void OnBoundsChanged( + const gfx::Rect& previous_bounds) override { + const gfx::Rect bounds = GetLocalBounds(); + auto highlight_path = std::make_unique<SkPath>(); + const gfx::Point center = bounds.CenterPoint(); + const int radius = views::LayoutProvider::Get() + ->GetCornerRadiusMetric( + views::EMPHASIS_MAXIMUM, bounds.size()); + highlight_path->addCircle( + center.x(), center.y(), radius); + SetProperty(views::kHighlightPathKey, + highlight_path.release()); + } +}; + +bool FindBarView::OnMousePressed( + const ui::MouseEvent& event) { + // The find text box only extends to the match count + // label. However, users expect to be able to click + // anywhere inside what looks like the find text + // box (including on or around the match_count label) + // and have focus brought to the find box. Cause + // clicks between the textfield and the find previous + // button to focus the textfield. + const int find_text_edge = + find_text_->bounds().right(); + const gfx::Rect focus_area( + find_text_edge, find_previous_button_->y(), + find_previous_button_->x() - find_text_edge, + find_previous_button_->height()); + if (!GetMirroredRect(focus_area).Contains( + event.location())) + return false; + find_text_->RequestFocus(); + return true; + +FindBarView::FindBarView(FindBarHost* host) + : find_bar_host_(host) { + auto find_text = std::make_unique<views::Textfield>(); + find_text_ = AddChildView(std::move(find_text)); + ... + auto find_previous_button = + std::make_unique<FindBarButton>(this); + views::ConfigureVectorImageButton( + find_previous_button.get()); + ... + auto find_next_button = + std::make_unique<FindBarButton>(this); + views::ConfigureVectorImageButton( + find_next_button.get()); + ... + auto close_button = + std::make_unique<FindBarButton>(this); + views::ConfigureVectorImageButton(close_button.get()); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +|||---||| + +## Don't invoke Layout() directly + +**Avoid direct calls to `Layout()`.** +These are typically used for three purposes: + +1. *Calling `Layout()` on `this`, when something that affects layout has +changed.* This forces a synchronous layout, which can lead to needless +work (e.g. if several sequential changes each trigger layout). Use +asynchronous layout\* instead. In many cases (such as +[the preferred size changing][] or +[a child needing layout][], +a `View` will automatically mark itself as needing layout; when necessary, call +[`InvalidateLayout()`][] to mark it manually. + +1. *Calling `Layout()` or `InvalidateLayout()` on some `View` to notify it +that something affecting its layout has changed.* Instead, ensure that +`View` is notified of the underlying change (via specific method overrides or +plumbing from a model object), and then invalidates its own layout when needed. + +1. *Calling `Layout()` on some `View` to "ensure it's up to date" before +reading some layout-related property off it.* Instead, plumb any relevant +events to the current object, then handle them directly (e.g. override +[`ChildPreferredSizeChanged()`][] or use a [`ViewObserver`][] +to monitor the target `View`; then update local state as necessary and trigger +handler methods). + +\* *How does asynchronous layout work?* In the browser, the compositor +periodically [requests a LayerTreeHost update][]. +This ultimately calls back to [`Widget::LayoutRootViewIfNecessary()`][], +recursively laying out invalidated `View`s within the `Widget`. In unittests, +this compositor-driven sequence never occurs, so it's necessary to +[call LayoutRootViewIfNecessary() manually][] when a test needs to ensure a +`View`'s layout is up-to-date. Many tests fail to do this, but currently pass +because something triggers Layout() directly; +accordingly, changing existing code from synchronous to asynchronous layout may +require adding `LayoutRootViewIfNecessary()` calls to (possibly many) tests, +and this is not a sign that the change is wrong. + +[the preferred size changing]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.cc;l=1673;drc=bc9a6d40468646be476c61b6637b51729bec7b6d +[a child needing layout]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.cc;l=777;drc=bc9a6d40468646be476c61b6637b51729bec7b6d +[`InvalidateLayout()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.h;l=735;drc=c06f6b339b47ce2388624aa9a89334ace38a71e4 +[`ChildPreferredSizeChanged()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view.h;l=1381;drc=c06f6b339b47ce2388624aa9a89334ace38a71e4 +[`ViewObserver`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/view_observer.h;l=17;drc=eb20fd77330dc4a89eecf17459263e5895e7f177 +[requests a LayerTreeHost update]: https://source.chromium.org/chromium/chromium/src/+/master:cc/trees/layer_tree_host.cc;l=304;drc=c06f6b339b47ce2388624aa9a89334ace38a71e4 +[`Widget::LayoutRootViewIfNecessary()`]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/widget/widget.h;l=946;drc=b1dcb398c454a576092d38d0d67db3709b2b2a9b +[call LayoutRootViewIfNecessary() manually]: https://source.chromium.org/chromium/chromium/src/+/master:ui/views/widget/widget_unittest.cc;l=3110;drc=c06f6b339b47ce2388624aa9a89334ace38a71e4 + +|||---||| + +##### + +**Avoid** + +[Current code][5] makes a direct and unnecessary call to Layout() + +[5]: https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/ui/views/media_router/cast_dialog_view.cc;l=349;drc=18ca2de542bfa53802639dc5c85762b5e7b5bef6 + +##### + +**Best practice** + +A better approach would be to call InvalidateLayout() and update the necessary tests. + +|||---||| + +|||---||| + +##### + +``` cpp +void CastDialogView::PopulateScrollView( + const std::vector<UIMediaSink>& sinks) { + ... + Layout(); +} + +TEST_F(CastDialogViewTest, PopulateDialog) { + CastDialogModel model = + CreateModelWithSinks({CreateAvailableSink()}); + InitializeDialogWithModel(model); + + EXPECT_TRUE(dialog_->ShouldShowCloseButton()); + EXPECT_EQ(model.dialog_header(), + dialog_->GetWindowTitle()); + EXPECT_EQ(ui::DIALOG_BUTTON_NONE, + dialog_->GetDialogButtons()); +} + + +``` + +##### + +``` cpp +void CastDialogView::PopulateScrollView( + const std::vector<UIMediaSink>& sinks) { + ... + InvalidateLayout(); +} + +TEST_F(CastDialogViewTest, PopulateDialog) { + CastDialogModel model = + CreateModelWithSinks({CreateAvailableSink()}); + InitializeDialogWithModel(model); + CastDialogView::GetCurrentDialogWidget() + ->LayoutRootViewIfNecessary(); + + EXPECT_TRUE(dialog_->ShouldShowCloseButton()); + EXPECT_EQ(model.dialog_header(), + dialog_->GetWindowTitle()); + EXPECT_EQ(ui::DIALOG_BUTTON_NONE, + dialog_->GetDialogButtons()); +} +``` + +|||---||| + + +## Consider different objects for different layouts + +If a surface needs very different appearances in different states (e.g. a +dialog whose content changes at each of several steps, or a container whose +layout toggles between disparate orientations), **use different `View`s to +contain the distinct states** instead of manually adding and removing +children and changing layout properties at each step. It's easier to reason +about several distinct fixed-layout `View`s than a single object whose layout +and children vary over time, and often more performant as well. + +|||---||| + +##### + +**Avoid** + +[Current code][6] holds both horizontal and vertical time views and replaces +the children and LayoutManager on orientation change. + +[6]: https://source.chromium.org/chromium/chromium/src/+/master:ash/system/time/time_view.h;l=35;drc=7d8bc7f807a433e6a127806e991fe780aa27ce77;bpv=1;bpt=0?originalUrl=https:%2F%2Fcs.chromium.org%2F + +##### + +**Best practice** + +A better approach would encapsulate the horizontal and vertical time views +into separate views. + +|||---||| + +|||---||| + +##### + +``` cpp +class ASH_EXPORT TimeView : public ActionableView, + public ClockObserver { + ... + private: + ... + std::unique_ptr<views::Label> horizontal_label_; + std::unique_ptr<views::Label> vertical_label_hours_; + std::unique_ptr<views::Label> vertical_label_minutes_; + ... +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +void TimeView::SetupLabels() { + horizontal_label_.reset(new views::Label()); + SetupLabel(horizontal_label_.get()); + vertical_label_hours_.reset(new views::Label()); + SetupLabel(vertical_label_hours_.get()); + vertical_label_minutes_.reset(new views::Label()); + SetupLabel(vertical_label_minutes_.get()); + ... +} + + + +void TimeView::UpdateClockLayout( + ClockLayout clock_layout) { + // Do nothing if the layout hasn't changed. + if (((clock_layout == ClockLayout::HORIZONTAL_CLOCK) ? + horizontal_label_ : vertical_label_hours_) + ->parent() == this) + return; + + SetBorder(views::NullBorder()); + if (clock_layout == ClockLayout::HORIZONTAL_CLOCK) { + RemoveChildView(vertical_label_hours_.get()); + RemoveChildView(vertical_label_minutes_.get()); + SetLayoutManager( + std::make_unique<views::FillLayout>()); + AddChildView(horizontal_label_.get()); + } else { + RemoveChildView(horizontal_label_.get()); + // Remove the current layout manager since it could + // be the FillLayout which only allows one child. + SetLayoutManager(nullptr); + // Pre-add the children since ownership is being + // retained by this. + AddChildView(vertical_label_hours_.get()); + AddChildView(vertical_label_minutes_.get()); + views::GridLayout* layout = + SetLayoutManager( + std::make_unique<views::GridLayout>()); + const int kColumnId = 0; + views::ColumnSet* columns = + layout->AddColumnSet(kColumnId); + columns->AddPaddingColumn( + 0, kVerticalClockLeftPadding); + columns->AddColumn(views::GridLayout::TRAILING, + views::GridLayout::CENTER, + 0, views::GridLayout::USE_PREF, + 0, 0); + layout->AddPaddingRow(0, kClockLeadingPadding); + layout->StartRow(0, kColumnId); + // Add the views as existing since ownership isn't + // being transferred. + layout->AddExistingView( + vertical_label_hours_.get()); + layout->StartRow(0, kColumnId); + layout->AddExistingView( + vertical_label_minutes_.get()); + layout->AddPaddingRow( + 0, kVerticalClockMinutesTopOffset); + } + Layout(); +} +``` + +##### + +``` cpp +class ASH_EXPORT TimeView : public ActionableView, + public ClockObserver { + ... + private: + class HorizontalLabelView; + class VerticalLabelView; + ... + HorizontalLabelView* horizontal_label_; + VerticalLabelView* vertical_label_; + ... +}; + +TimeView::HorizontalLabelView::HorizontalLabelView() { + SetLayoutManager( + std::make_unique<views::FillLayout>()); + views::Label* time_label = + AddChildView(std::make_unique<views::Label>()); + SetupLabels(time_label); + ... +} + +TimeView::VerticalLabelView::VerticalLabelView() { + views::GridLayout* layout = + SetLayoutManager( + std::make_unique<views::GridLayout>()); + views::Label* label_hours = + AddChildView(std::make_unique<views::Label>()); + views::Label* label_minutes = + AddChildView(std::make_unique<views::Label>()); + SetupLabel(label_hours); + SetupLabel(label_minutes); + const int kColumnId = 0; + views::ColumnSet* columns = + layout->AddColumnSet(kColumnId); + columns->AddPaddingColumn( + 0, kVerticalClockLeftPadding); + columns->AddColumn( + views::GridLayout::TRAILING, + views::GridLayout::CENTER, + 0, views::GridLayout::USE_PREF, 0, 0); + layout->AddPaddingRow(0, kClockLeadingPadding); + layout->StartRow(0, kColumnId); + // Add the views as existing since ownership isn't + // being transferred. + layout->AddExistingView(label_hours); + layout->StartRow(0, kColumnId); + layout->AddExistingView(label_minutes); + layout->AddPaddingRow( + 0, kVerticalClockMinutesTopOffset); + ... +} + +void TimeView::TimeView(ClockLayout clock_layout, + ClockModel* model) { + ... + horizontal_label_ = + AddChildView( + std::make_unique<HorizontalLabelView>()); + vertical_label_ = + AddChildView( + std::make_unique<VerticalLabelView()); + ... +} + +void TimeView::UpdateClockLayout( + ClockLayout clock_layout) { + ... + const bool is_horizontal = + clock_layout == ClockLayout::HORIZONTAL_CLOCK; + horizontal_label_->SetVisible(is_horizontal); + vertical_label_->SetVisible(!is_horizontal); + InvalidateLayout(); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +|||---||| +
diff --git a/docs/ui/learn/index.md b/docs/ui/learn/index.md index 5608832..8594fad0 100644 --- a/docs/ui/learn/index.md +++ b/docs/ui/learn/index.md
@@ -3,6 +3,7 @@ # Best Practices * [Colors](bestpractices/colors.md): How to work with Chromium colors. +* [Layout](bestpractices/layout.md): How to use Views layout. * [Ownership](bestpractices/ownership.md): How to manage Views object lifetimes. # Architecture Overview
diff --git a/fuchsia/base/BUILD.gn b/fuchsia/base/BUILD.gn index 2dba968..ebb50a6 100644 --- a/fuchsia/base/BUILD.gn +++ b/fuchsia/base/BUILD.gn
@@ -15,6 +15,7 @@ "config_reader.cc", "fuchsia_dir_scheme.cc", "init_logging.cc", + "inspect.cc", "mem_buffer_util.cc", "string_util.cc", ] @@ -22,12 +23,16 @@ "config_reader.h", "fuchsia_dir_scheme.h", "init_logging.h", + "inspect.h", "mem_buffer_util.h", "string_util.h", ] deps = [ "//base", + "//components/version_info", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem", + "//third_party/fuchsia-sdk/sdk/pkg/fdio", + "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp", "//url", ] } @@ -120,6 +125,7 @@ test("cr_fuchsia_base_unittests") { sources = [ "agent_impl_unittests.cc", + "inspect_unittest.cc", "legacymetrics_client_unittest.cc", "legacymetrics_histogram_flattener_unittest.cc", "legacymetrics_user_event_recorder_unittest.cc", @@ -132,6 +138,9 @@ "//base:testfidl", "//base/test:run_all_unittests", "//base/test:test_support", + "//components/version_info", "//testing/gtest", + "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp", + "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp", ] }
diff --git a/fuchsia/base/DEPS b/fuchsia/base/DEPS index 9455f2c..5ded5f1b 100644 --- a/fuchsia/base/DEPS +++ b/fuchsia/base/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/version_info", "+mojo/public", "+third_party/blink/public/common/messaging", "+third_party/blink/public/mojom/messaging",
diff --git a/fuchsia/base/inspect.cc b/fuchsia/base/inspect.cc new file mode 100644 index 0000000..775ae986 --- /dev/null +++ b/fuchsia/base/inspect.cc
@@ -0,0 +1,28 @@ +// Copyright 2020 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/base/inspect.h" + +#include <lib/sys/inspect/cpp/component.h> + +#include "components/version_info/version_info.h" + +namespace cr_fuchsia { + +namespace { +const char kVersion[] = "version"; +const char kLastChange[] = "last_change_revision"; +} // namespace + +void PublishVersionInfoToInspect(sys::ComponentInspector* inspector) { + // These values are managed by the inspector, since they won't be updated over + // the lifetime of the component. + // TODO(https://crbug.com/1077428): Add release channel. + inspector->root().CreateString(kVersion, version_info::GetVersionNumber(), + inspector); + inspector->root().CreateString(kLastChange, version_info::GetLastChange(), + inspector); +} + +} // namespace cr_fuchsia
diff --git a/fuchsia/base/inspect.h b/fuchsia/base/inspect.h new file mode 100644 index 0000000..4d8d35335 --- /dev/null +++ b/fuchsia/base/inspect.h
@@ -0,0 +1,20 @@ +// Copyright 2020 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_BASE_INSPECT_H_ +#define FUCHSIA_BASE_INSPECT_H_ + +namespace sys { +class ComponentInspector; +} // namespace sys + +namespace cr_fuchsia { + +// Publish the Chromium version via the Inspect API. The lifetime of +// |inspector| has to be the same as the component it belongs to. +void PublishVersionInfoToInspect(sys::ComponentInspector* inspector); + +} // namespace cr_fuchsia + +#endif // FUCHSIA_BASE_INSPECT_H_ \ No newline at end of file
diff --git a/fuchsia/base/inspect_unittest.cc b/fuchsia/base/inspect_unittest.cc new file mode 100644 index 0000000..7a2bff50 --- /dev/null +++ b/fuchsia/base/inspect_unittest.cc
@@ -0,0 +1,95 @@ +// Copyright 2020 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/base/inspect.h" + +#include <lib/fdio/directory.h> +#include <lib/inspect/cpp/hierarchy.h> +#include <lib/inspect/cpp/reader.h> +#include <lib/inspect/service/cpp/reader.h> +#include <lib/sys/cpp/component_context.h> +#include <lib/sys/inspect/cpp/component.h> +#include <cstdint> +#include <memory> + +#include "base/task/single_thread_task_executor.h" +#include "base/test/task_environment.h" +#include "components/version_info/version_info.h" +#include "fuchsia/base/mem_buffer_util.h" +#include "fuchsia/base/string_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cr_fuchsia { + +namespace { + +const char kVersion[] = "version"; +const char kLastChange[] = "last_change_revision"; + +class InspectTest : public ::testing::Test { + public: + InspectTest() { + fidl::InterfaceHandle<fuchsia::io::Directory> incoming_directory; + auto incoming_services = + std::make_shared<sys::ServiceDirectory>(std::move(incoming_directory)); + context_ = std::make_unique<sys::ComponentContext>( + std::move(incoming_services), + published_root_directory_.NewRequest().TakeChannel()); + inspector_ = std::make_unique<sys::ComponentInspector>(context_.get()); + base::RunLoop().RunUntilIdle(); + } + + InspectTest(const InspectTest&) = delete; + InspectTest& operator=(const InspectTest&) = delete; + + protected: + base::test::SingleThreadTaskEnvironment task_environment_{ + base::test::SingleThreadTaskEnvironment::MainThreadType::IO}; + std::unique_ptr<sys::ComponentContext> context_; + fidl::InterfaceHandle<fuchsia::io::Directory> published_root_directory_; + std::unique_ptr<sys::ComponentInspector> inspector_; +}; + +} // namespace + +TEST_F(InspectTest, PublishVersionInfoToInspect) { + cr_fuchsia::PublishVersionInfoToInspect(inspector_.get()); + fidl::InterfaceHandle<fuchsia::io::Directory> directory; + zx_status_t status = fdio_service_connect_at( + published_root_directory_.channel().get(), "diagnostics", + directory.NewRequest().TakeChannel().release()); + ASSERT_EQ(ZX_OK, status); + std::unique_ptr<sys::ServiceDirectory> diagnostics = + std::make_unique<sys::ServiceDirectory>(std::move(directory)); + + // Access the inspect::Tree where the data is served. |tree| is in the + // directory created for the test, not the diagnostics directory for the test + // component. + fuchsia::inspect::TreePtr tree; + diagnostics->Connect(tree.NewRequest()); + fuchsia::inspect::TreeContent content; + base::RunLoop run_loop; + tree->GetContent([&content, &run_loop](fuchsia::inspect::TreeContent c) { + content = std::move(c); + run_loop.Quit(); + }); + run_loop.Run(); + + // Parse the data as an inspect::Hierarchy. + ASSERT_TRUE(content.has_buffer()); + std::string buffer_data; + cr_fuchsia::StringFromMemBuffer(content.buffer(), &buffer_data); + inspect::Hierarchy hierarchy = + inspect::ReadFromBuffer(cr_fuchsia::StringToBytes(buffer_data)) + .take_value(); + + auto* property = + hierarchy.node().get_property<inspect::StringPropertyValue>(kVersion); + EXPECT_EQ(property->value(), version_info::GetVersionNumber()); + property = + hierarchy.node().get_property<inspect::StringPropertyValue>(kLastChange); + EXPECT_EQ(property->value(), version_info::GetLastChange()); +} + +} // namespace cr_fuchsia
diff --git a/fuchsia/engine/context_provider_main.cc b/fuchsia/engine/context_provider_main.cc index 5019591..6a1622c 100644 --- a/fuchsia/engine/context_provider_main.cc +++ b/fuchsia/engine/context_provider_main.cc
@@ -10,6 +10,7 @@ #include "base/command_line.h" #include "base/fuchsia/default_context.h" +#include "base/fuchsia/process_context.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/logging.h" #include "base/message_loop/message_pump_type.h" @@ -17,6 +18,7 @@ #include "base/task/single_thread_task_executor.h" #include "components/version_info/version_info.h" #include "fuchsia/base/init_logging.h" +#include "fuchsia/base/inspect.h" #include "fuchsia/base/lifecycle_impl.h" #include "fuchsia/engine/context_provider_impl.h" @@ -68,6 +70,9 @@ base::fuchsia::ScopedServiceBinding<fuchsia::web::Debug> debug_binding( directory->debug_dir(), &context_provider); + // Publish version information for this component to Inspect. + cr_fuchsia::PublishVersionInfoToInspect(base::ComponentInspectorForProcess()); + // Publish the Lifecycle service, used by the framework to request that the // service terminate. base::RunLoop run_loop;
diff --git a/fuchsia/runners/cast/main.cc b/fuchsia/runners/cast/main.cc index e6e0f47..643e27c3 100644 --- a/fuchsia/runners/cast/main.cc +++ b/fuchsia/runners/cast/main.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "base/fuchsia/default_context.h" +#include "base/fuchsia/process_context.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/message_loop/message_pump_type.h" #include "base/optional.h" @@ -15,6 +16,7 @@ #include "fuchsia/base/config_reader.h" #include "fuchsia/base/fuchsia_dir_scheme.h" #include "fuchsia/base/init_logging.h" +#include "fuchsia/base/inspect.h" #include "fuchsia/runners/cast/cast_runner.h" namespace { @@ -53,6 +55,9 @@ ->outgoing() ->ServeFromStartupInfo(); + // Publish version information for this component to Inspect. + cr_fuchsia::PublishVersionInfoToInspect(base::ComponentInspectorForProcess()); + // Run until there are no Components, or the last service client channel is // closed. // TODO(https://crbug.com/952560): Implement Components v2 graceful exit.
diff --git a/fuchsia/runners/web/main.cc b/fuchsia/runners/web/main.cc index 719419d8..5209d706 100644 --- a/fuchsia/runners/web/main.cc +++ b/fuchsia/runners/web/main.cc
@@ -7,12 +7,14 @@ #include "base/command_line.h" #include "base/fuchsia/default_context.h" #include "base/fuchsia/file_utils.h" +#include "base/fuchsia/process_context.h" #include "base/fuchsia/scoped_service_binding.h" #include "base/message_loop/message_pump_type.h" #include "base/run_loop.h" #include "base/task/single_thread_task_executor.h" #include "fuchsia/base/fuchsia_dir_scheme.h" #include "fuchsia/base/init_logging.h" +#include "fuchsia/base/inspect.h" #include "fuchsia/runners/buildflags.h" #include "fuchsia/runners/common/web_content_runner.h" @@ -67,6 +69,9 @@ ->outgoing() ->ServeFromStartupInfo(); + // Publish version information for this component to Inspect. + cr_fuchsia::PublishVersionInfoToInspect(base::ComponentInspectorForProcess()); + // Run until there are no Components, or the last service client channel is // closed. // TODO(https://crbug.com/952560): Implement Components v2 graceful exit.
diff --git a/google_apis/gcm/base/socket_stream_unittest.cc b/google_apis/gcm/base/socket_stream_unittest.cc index d8ea8fbf..079d118 100644 --- a/google_apis/gcm/base/socket_stream_unittest.cc +++ b/google_apis/gcm/base/socket_stream_unittest.cc
@@ -20,6 +20,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/ip_address.h" +#include "net/base/network_isolation_key.h" #include "net/log/net_log_source.h" #include "net/socket/socket_test_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" @@ -28,6 +29,7 @@ #include "services/network/network_service.h" #include "services/network/public/mojom/proxy_resolving_socket.mojom.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/origin.h" namespace gcm { namespace { @@ -231,8 +233,12 @@ network::mojom::ProxyResolvingSocketOptionsPtr options = network::mojom::ProxyResolvingSocketOptions::New(); options->use_tls = true; + const url::Origin kOrigin = url::Origin::Create(kDestination); mojo_socket_factory_remote_->CreateProxyResolvingSocket( - kDestination, std::move(options), + kDestination, + net::NetworkIsolationKey(kOrigin /* top_frame_origin */, + kOrigin /* frame_origin */), + std::move(options), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), mojo_socket_remote_.BindNewPipeAndPassReceiver(), mojo::NullRemote() /* observer */,
diff --git a/google_apis/gcm/engine/connection_factory_impl.cc b/google_apis/gcm/engine/connection_factory_impl.cc index 0e20ff33..e4d2cf8 100644 --- a/google_apis/gcm/engine/connection_factory_impl.cc +++ b/google_apis/gcm/engine/connection_factory_impl.cc
@@ -17,6 +17,7 @@ #include "google_apis/gcm/protocol/mcs.pb.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/http/http_request_headers.h" #include "net/http/proxy_fallback.h" #include "net/log/net_log_source_type.h" @@ -26,6 +27,8 @@ #include "net/ssl/ssl_config_service.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "services/network/public/mojom/tcp_socket.mojom.h" +#include "url/gurl.h" +#include "url/origin.h" namespace gcm { @@ -359,8 +362,13 @@ network::mojom::ProxyResolvingSocketOptionsPtr options = network::mojom::ProxyResolvingSocketOptions::New(); options->use_tls = true; + // |current_endpoint| is always a Google URL, so this NetworkIsolationKey will + // be the same for all callers, and will allow pooling all connections to GCM + // in one socket connection, if an H2 or QUIC proxy is in use. + auto origin = url::Origin::Create(current_endpoint); + net::NetworkIsolationKey network_isolation_key(origin, origin); socket_factory_->CreateProxyResolvingSocket( - current_endpoint, std::move(options), + current_endpoint, std::move(network_isolation_key), std::move(options), net::MutableNetworkTrafficAnnotationTag(traffic_annotation), socket_.BindNewPipeAndPassReceiver(), mojo::NullRemote() /* observer */, base::BindOnce(&ConnectionFactoryImpl::OnConnectDone,
diff --git a/google_apis/gcm/engine/connection_handler_impl_unittest.cc b/google_apis/gcm/engine/connection_handler_impl_unittest.cc index 2b7e485f..27003b4 100644 --- a/google_apis/gcm/engine/connection_handler_impl_unittest.cc +++ b/google_apis/gcm/engine/connection_handler_impl_unittest.cc
@@ -27,6 +27,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "net/base/ip_address.h" +#include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/log/net_log_source.h" #include "net/socket/socket_test_util.h" @@ -38,6 +39,7 @@ #include "services/network/network_service.h" #include "services/network/public/mojom/proxy_resolving_socket.mojom.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/origin.h" namespace gcm { namespace { @@ -249,8 +251,12 @@ network::mojom::ProxyResolvingSocketOptions::New(); options->use_tls = true; mojo_socket_remote_.reset(); + const url::Origin kOrigin = url::Origin::Create(kDestination); mojo_socket_factory_remote_->CreateProxyResolvingSocket( - kDestination, std::move(options), + kDestination, + net::NetworkIsolationKey(kOrigin /* top_frame_origin */, + kOrigin /* frame_origin */), + std::move(options), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), mojo_socket_remote_.BindNewPipeAndPassReceiver(), mojo::NullRemote() /* observer */,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index a0dc39c..3405cd9 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1029,6 +1029,12 @@ // Return 0 if no stencil attachment. GLenum GetBoundFramebufferStencilFormat(GLenum target); + gfx::Vector2d GetBoundFramebufferDrawOffset() const { + if (GetBoundDrawFramebuffer() || offscreen_target_frame_buffer_.get()) + return gfx::Vector2d(); + return surface_->GetDrawOffset(); + } + void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i); // Wrapper for CompressedTexImage{2|3}D commands. @@ -6400,9 +6406,19 @@ return; state_.fbo_binding_for_scissor_workaround_dirty = false; - if (workarounds().restore_scissor_on_fbo_change) { - api()->glScissorFn(state_.scissor_x, state_.scissor_y, state_.scissor_width, - state_.scissor_height); + if (supports_dc_layers_) { + gfx::Vector2d draw_offset = GetBoundFramebufferDrawOffset(); + api()->glViewportFn(state_.viewport_x + draw_offset.x(), + state_.viewport_y + draw_offset.y(), + state_.viewport_width, state_.viewport_height); + } + + if (workarounds().restore_scissor_on_fbo_change || supports_dc_layers_) { + // The driver forgets the correct scissor when modifying the FBO binding. + gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset(); + api()->glScissorFn(state_.scissor_x + scissor_offset.x(), + state_.scissor_y + scissor_offset.y(), + state_.scissor_width, state_.scissor_height); } if (workarounds().restore_scissor_on_fbo_change) { @@ -8519,8 +8535,10 @@ state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); RestoreDeviceWindowRectangles(); - api()->glScissorFn(state_.scissor_x, state_.scissor_y, state_.scissor_width, - state_.scissor_height); + gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset(); + api()->glScissorFn(state_.scissor_x + scissor_offset.x(), + state_.scissor_y + scissor_offset.y(), + state_.scissor_width, state_.scissor_height); } GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { @@ -13046,14 +13064,17 @@ state_.viewport_y = y; state_.viewport_width = std::min(width, viewport_max_width_); state_.viewport_height = std::min(height, viewport_max_height_); - api()->glViewportFn(x, y, width, height); + gfx::Vector2d viewport_offset = GetBoundFramebufferDrawOffset(); + api()->glViewportFn(x + viewport_offset.x(), y + viewport_offset.y(), width, + height); } void GLES2DecoderImpl::DoScissor(GLint x, GLint y, GLsizei width, GLsizei height) { - api()->glScissorFn(x, y, width, height); + gfx::Vector2d draw_offset = GetBoundFramebufferDrawOffset(); + api()->glScissorFn(x + draw_offset.x(), y + draw_offset.y(), width, height); } error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( @@ -14417,7 +14438,9 @@ api()->glClearDepthFn(1.0f); state_.SetDeviceDepthMask(GL_TRUE); state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); - api()->glScissorFn(xoffset, yoffset, width, height); + gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset(); + api()->glScissorFn(xoffset + scissor_offset.x(), + yoffset + scissor_offset.y(), width, height); ClearDeviceWindowRectangles(); api()->glClearFn((have_color ? GL_COLOR_BUFFER_BIT : 0) |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc index dc4d893..0957b626 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -1194,6 +1194,12 @@ attrib_helper.offscreen_framebuffer_size.height()); } + // Initialize the tracked scissor and viewport state and then apply the + // surface offsets if needed. + api()->glGetIntegervFn(GL_VIEWPORT, viewport_); + api()->glGetIntegervFn(GL_SCISSOR_BOX, scissor_); + ApplySurfaceDrawOffset(); + #if defined(OS_MACOSX) // On mac we need the ANGLE_texture_rectangle extension to support IOSurface // backbuffers, but we don't want it exposed to WebGL user shaders. This @@ -2116,6 +2122,24 @@ } break; + case GL_VIEWPORT: + // The applied viewport and scissor could be offset by the current + // surface, return the tracked values instead + if (length < 4) { + return error::kInvalidArguments; + } + std::copy(std::begin(viewport_), std::end(viewport_), params); + break; + + case GL_SCISSOR_BOX: + // The applied viewport and scissor could be offset by the current + // surface, return the tracked values instead + if (length < 4) { + return error::kInvalidArguments; + } + std::copy(std::begin(scissor_), std::end(scissor_), params); + break; + default: break; } @@ -2890,6 +2914,27 @@ } } +gfx::Vector2d GLES2DecoderPassthroughImpl::GetSurfaceDrawOffset() const { + if (bound_draw_framebuffer_ != 0 || offscreen_) { + return gfx::Vector2d(); + } + return surface_->GetDrawOffset(); +} + +void GLES2DecoderPassthroughImpl::ApplySurfaceDrawOffset() { + if (offscreen_ || !surface_->SupportsDCLayers()) { + return; + } + + gfx::Vector2d framebuffer_offset = GetSurfaceDrawOffset(); + api()->glViewportFn(viewport_[0] + framebuffer_offset.x(), + viewport_[1] + framebuffer_offset.y(), viewport_[2], + viewport_[3]); + api()->glScissorFn(scissor_[0] + framebuffer_offset.x(), + scissor_[1] + framebuffer_offset.y(), scissor_[2], + scissor_[3]); +} + bool GLES2DecoderPassthroughImpl::CheckErrorCallbackState() { bool had_error_ = had_error_callback_; had_error_callback_ = false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h index f84982bcf..c7e886e2 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -609,6 +609,12 @@ scoped_refptr<TexturePassthrough> texture; }; + // Tracked viewport and scissor state for surface offset + GLint viewport_[4] = {0, 0, 0, 0}; + GLint scissor_[4] = {0, 0, 0, 0}; + gfx::Vector2d GetSurfaceDrawOffset() const; + void ApplySurfaceDrawOffset(); + // Use a limit that is at least ANGLE's IMPLEMENTATION_MAX_ACTIVE_TEXTURES // constant static constexpr size_t kMaxTextureUnits = 64;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index c3e5a308..2fd975d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -262,6 +262,17 @@ memcpy(data->data() + old_size.ValueOrDie(), str, len); } +void AssignGLRectangle(GLint rectangle[4], + GLint x, + GLint y, + GLint width, + GLint height) { + rectangle[0] = x; + rectangle[1] = y; + rectangle[2] = width; + rectangle[3] = height; +} + // In order to minimize the amount of data copied, the command buffer client // unpack pixels before sending the glTex[Sub]Image[2|3]D calls. The only // parameter it doesn't handle is the alignment. Resetting the unpack state is @@ -489,6 +500,13 @@ break; } + // Resync the surface offset if the draw framebuffer has changed to or from + // the default framebuffer + if (draw_framebuffer_changed && bound_draw_framebuffer_ != framebuffer && + (bound_draw_framebuffer_ == 0 || framebuffer == 0)) { + ApplySurfaceDrawOffset(); + } + return error::kNoError; } @@ -1028,6 +1046,9 @@ api()->glBindFramebufferEXTFn( GL_DRAW_FRAMEBUFFER, emulated_back_buffer_->framebuffer_service_id); } + + // Update the surface offset if the bound draw framebuffer is deleted + ApplySurfaceDrawOffset(); } if (framebuffer == bound_read_framebuffer_) { bound_read_framebuffer_ = 0; @@ -2604,7 +2625,19 @@ GLint y, GLsizei width, GLsizei height) { - api()->glScissorFn(x, y, width, height); + CheckErrorCallbackState(); + + gfx::Vector2d scissor_offset = GetSurfaceDrawOffset(); + api()->glScissorFn(x + scissor_offset.x(), y + scissor_offset.y(), width, + height); + + if (CheckErrorCallbackState()) { + // Skip any state tracking updates if an error was generated + return error::kNoError; + } + + AssignGLRectangle(scissor_, x, y, width, height); + return error::kNoError; } @@ -3250,7 +3283,20 @@ GLint y, GLsizei width, GLsizei height) { - api()->glViewportFn(x, y, width, height); + CheckErrorCallbackState(); + + gfx::Vector2d viewport_offset = GetSurfaceDrawOffset(); + api()->glViewportFn(x + viewport_offset.x(), y + viewport_offset.y(), width, + height); + + if (CheckErrorCallbackState()) { + // Skip any state tracking updates if an error was generated. Viewport may + // have been out of bounds. + return error::kNoError; + } + + AssignGLRectangle(viewport_, x, y, width, height); + return error::kNoError; } @@ -5156,6 +5202,8 @@ return error::kLostContext; } + ApplySurfaceDrawOffset(); + return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc index 98cd052..04ecdd60 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_framebuffers.cc
@@ -3915,6 +3915,106 @@ } } +class GLES2DecoderTestWithDrawRectangle : public GLES2DecoderTest { + void SetUp() override { + surface_supports_draw_rectangle_ = true; + GLES2DecoderTest::SetUp(); + } +}; + +// Test that the draw offset is correctly honored when SetDrawRectangle is +// supported. +TEST_P(GLES2DecoderTestWithDrawRectangle, FramebufferDrawRectangleClear) { + EXPECT_CALL(*gl_, Scissor(101, 202, 3, 4)).Times(1).RetiresOnSaturation(); + cmds::Scissor scissor_cmd; + scissor_cmd.Init(1, 2, 3, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(scissor_cmd)); + + // Scissor and Viewport should be restored to (0,0) offset on when clearing + // a framebuffer. + { + const GLuint kFBOClientTextureId = 4100; + const GLuint kFBOServiceTextureId = 4101; + + // Register a texture id. + EXPECT_CALL(*gl_, GenTextures(_, _)) + .WillOnce(SetArgPointee<1>(kFBOServiceTextureId)) + .RetiresOnSaturation(); + GenHelper<cmds::GenTexturesImmediate>(kFBOClientTextureId); + + // Setup "render to" texture. + DoBindTexture(GL_TEXTURE_2D, kFBOClientTextureId, kFBOServiceTextureId); + DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + 0, 0); + DoBindFramebuffer(GL_FRAMEBUFFER, client_framebuffer_id_, + kServiceFramebufferId); + DoFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + kFBOClientTextureId, kFBOServiceTextureId, 0, + GL_NO_ERROR); + // Set scissor rect and enable GL_SCISSOR_TEST to make sure we re-enable it + // and restore the rect again after the clear. + DoEnableDisable(GL_SCISSOR_TEST, true); + EXPECT_CALL(*gl_, Viewport(0, 0, 128, 64)).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*gl_, Scissor(1, 2, 3, 4)).Times(1).RetiresOnSaturation(); + + // Setup "render from" texture. + SetupTexture(); + + SetupExpectationsForFramebufferClearing(GL_FRAMEBUFFER, // target + GL_COLOR_BUFFER_BIT, // clear bits + 0, 0, 0, + 0, // color + 0, // stencil + 1.0f, // depth + true, // scissor test + 1, 2, 3, 4); + SetupExpectationsForApplyingDirtyState(false, // Framebuffer is RGB + false, // Framebuffer has depth + false, // Framebuffer has stencil + 0x1111, // color bits + false, // depth mask + false, // depth enabled + 0, // front stencil mask + 0, // back stencil mask + false); // stencil enabled + + EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)) + .Times(1) + .RetiresOnSaturation(); + + cmds::Clear cmd; + cmd.Init(GL_COLOR_BUFFER_BIT); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } + + // Check that the draw offset is used when switching to the default + // framebuffer and clearing it. + { + DoBindFramebuffer(GL_FRAMEBUFFER, 0, 0); + EXPECT_CALL(*gl_, Clear(GL_COLOR_BUFFER_BIT)) + .Times(1) + .RetiresOnSaturation(); + SetupExpectationsForColorMask(true, true, true, true); + SetupExpectationsForDepthMask(true); + SetupExpectationsForStencilMask(0, 0); + SetupExpectationsForEnableDisable(GL_DEPTH_TEST, false); + SetupExpectationsForEnableDisable(GL_STENCIL_TEST, false); + EXPECT_CALL(*gl_, Viewport(100, 200, 128, 64)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, Scissor(101, 202, 3, 4)).Times(1).RetiresOnSaturation(); + cmds::Clear cmd; + cmd.Init(GL_COLOR_BUFFER_BIT); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } +} + +INSTANTIATE_TEST_SUITE_P(Service, + GLES2DecoderTestWithDrawRectangle, + ::testing::Bool()); + TEST_P(GLES2DecoderManualInitTest, MESAFramebufferFlipYExtensionEnabled) { InitState init; init.gl_version = "OpenGL ES 3.1";
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm b/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm index 4e6c7b6d..ebe1044 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm +++ b/gpu/command_buffer/service/shared_image_backing_factory_iosurface.mm
@@ -110,28 +110,11 @@ viz::ResourceFormat format) { TRACE_EVENT0("gpu", "SharedImageBackingFactoryIOSurface::CreateMetalTexture"); base::scoped_nsprotocol<id<MTLTexture>> mtl_texture; - MTLPixelFormat mtl_pixel_format; - switch (format) { - case viz::RED_8: - case viz::ALPHA_8: - case viz::LUMINANCE_8: - mtl_pixel_format = MTLPixelFormatR8Unorm; - break; - case viz::RG_88: - mtl_pixel_format = MTLPixelFormatRG8Unorm; - break; - case viz::RGBA_8888: - mtl_pixel_format = MTLPixelFormatRGBA8Unorm; - break; - case viz::BGRA_8888: - mtl_pixel_format = MTLPixelFormatBGRA8Unorm; - break; - default: - // TODO(https://crbug.com/952063): Add support for all formats supported - // by GLImageIOSurface. - DLOG(ERROR) << "Resource format not yet supported in Metal."; - return mtl_texture; - } + MTLPixelFormat mtl_pixel_format = + static_cast<MTLPixelFormat>(viz::ToMTLPixelFormat(format)); + if (mtl_pixel_format == MTLPixelFormatInvalid) + return mtl_texture; + base::scoped_nsobject<MTLTextureDescriptor> mtl_tex_desc( [MTLTextureDescriptor new]); [mtl_tex_desc setTextureType:MTLTextureType2D];
diff --git a/gpu/ipc/service/image_transport_surface_win.cc b/gpu/ipc/service/image_transport_surface_win.cc index dd52c11e..3cc8901 100644 --- a/gpu/ipc/service/image_transport_surface_win.cc +++ b/gpu/ipc/service/image_transport_surface_win.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/win/windows_version.h" +#include "components/viz/common/features.h" #include "gpu/command_buffer/service/feature_info.h" #include "gpu/config/gpu_preferences.h" #include "gpu/ipc/service/pass_through_image_transport_surface.h" @@ -41,6 +42,7 @@ settings.disable_larger_than_screen_overlays = workarounds.disable_larger_than_screen_overlays; settings.disable_vp_scaling = workarounds.disable_vp_scaling; + settings.use_angle_texture_offset = features::IsUsingSkiaRenderer(); auto vsync_callback = delegate->GetGpuVSyncCallback(); auto dc_surface = base::MakeRefCounted<gl::DirectCompositionSurfaceWin>( std::move(vsync_provider), std::move(vsync_callback), surface_handle,
diff --git a/ios/third_party/webkit/BUILD.gn b/ios/third_party/webkit/BUILD.gn index f9b008c..d538189 100644 --- a/ios/third_party/webkit/BUILD.gn +++ b/ios/third_party/webkit/BUILD.gn
@@ -110,7 +110,7 @@ "$_webkit_ios_out_product_dir/com.apple.WebKit.WebContent.xpc/com.apple.WebKit.WebContent.Development", ] args = [ - "--ios-simulator", + "--ios_simulator", "--asan", "--output_dir", rebase_path("$_webkit_ios_out_base_dir"),
diff --git a/jingle/glue/network_service_async_socket.cc b/jingle/glue/network_service_async_socket.cc index e6501bb1..ef26e71 100644 --- a/jingle/glue/network_service_async_socket.cc +++ b/jingle/glue/network_service_async_socket.cc
@@ -17,6 +17,9 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/host_port_pair.h" #include "net/base/io_buffer.h" +#include "net/base/network_isolation_key.h" +#include "url/gurl.h" +#include "url/origin.h" namespace jingle_glue { @@ -164,8 +167,13 @@ network::mojom::ProxyResolvingSocketOptions::New(); options->use_tls = false; options->fake_tls_handshake = use_fake_tls_handshake_; + GURL url("https://" + address.ToString()); + auto origin = url::Origin::Create(url); socket_factory_->CreateProxyResolvingSocket( - GURL("https://" + address.ToString()), std::move(options), + url, + net::NetworkIsolationKey(origin /* top_frame_origin */, + origin /* frame_origin */), + std::move(options), net::MutableNetworkTrafficAnnotationTag(traffic_annotation_), socket_.BindNewPipeAndPassReceiver(), std::move(socket_observer), base::BindOnce(&NetworkServiceAsyncSocket::ProcessConnectDone,
diff --git a/jingle/glue/network_service_async_socket_unittest.cc b/jingle/glue/network_service_async_socket_unittest.cc index 246d17d9..8da261f 100644 --- a/jingle/glue/network_service_async_socket_unittest.cc +++ b/jingle/glue/network_service_async_socket_unittest.cc
@@ -30,6 +30,7 @@ #include "net/base/host_port_pair.h" #include "net/base/ip_address.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/cert/mock_cert_verifier.h" #include "net/http/transport_security_state.h" #include "net/log/net_log_source.h" @@ -42,6 +43,7 @@ #include "services/network/public/mojom/proxy_resolving_socket.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/webrtc/rtc_base/third_party/sigslot/sigslot.h" +#include "url/origin.h" namespace jingle_glue { @@ -191,11 +193,16 @@ // mojom::ProxyResolvingSocketFactory implementation. void CreateProxyResolvingSocket( const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, network::mojom::ProxyResolvingSocketOptionsPtr options, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojo::PendingReceiver<network::mojom::ProxyResolvingSocket> receiver, mojo::PendingRemote<network::mojom::SocketObserver> observer, CreateProxyResolvingSocketCallback callback) override { + url::Origin origin = url::Origin::Create(url); + EXPECT_EQ(net::NetworkIsolationKey(origin /* top_frame_origin */, + origin /* frame_origin */), + network_isolation_key); auto socket = std::make_unique<MockProxyResolvingSocket>(); socket_raw_ = socket.get(); proxy_resolving_socket_receivers_.Add(std::move(socket),
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index e234865..c130d18 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -464,6 +464,9 @@ const base::Feature kHardwareSecureDecryption{ "HardwareSecureDecryption", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kWakeLockOptimisationHiddenMuted{ + "kWakeLockOptimisationHiddenMuted", base::FEATURE_ENABLED_BY_DEFAULT}; + // Enables encrypted AV1 support in EME requestMediaKeySystemAccess() query by // Widevine key system if it is also supported by the underlying Widevine CDM. // This feature does not affect the actual playback of encrypted AV1 if it's
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 10821194..1529fa8 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -171,6 +171,7 @@ MEDIA_EXPORT extern const base::Feature kVaapiVP8Encoder; MEDIA_EXPORT extern const base::Feature kVaapiVP9Encoder; MEDIA_EXPORT extern const base::Feature kVideoBlitColorAccuracy; +MEDIA_EXPORT extern const base::Feature kWakeLockOptimisationHiddenMuted; MEDIA_EXPORT extern const base::Feature kWidevineAv1; MEDIA_EXPORT extern const base::Feature kWidevineAv1ForceSupportForTesting;
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc index 4f840cf8b..1955d56 100644 --- a/media/formats/mp4/mp4_stream_parser_unittest.cc +++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/mock_callback.h" #include "base/time/time.h" #include "media/base/audio_decoder_config.h" #include "media/base/decoder_buffer.h" @@ -43,6 +44,21 @@ namespace media { namespace mp4 { +namespace { + +// Useful in single-track test media cases that need to verify +// keyframe/non-keyframe sequence in output of parse. +enum class Keyframeness { + kKeyframe = 0, + kNonKeyframe, +}; + +// Tells gtest how to print our Keyframeness enum values. +std::ostream& operator<<(std::ostream& os, Keyframeness k) { + return os << (k == Keyframeness::kKeyframe ? "kKeyframe" : "kNonKeyframe"); +} + +} // namespace // Matchers for verifying common media log entry strings. MATCHER(SampleEncryptionInfoUnavailableLog, "") { @@ -80,6 +96,7 @@ StreamParser::TrackId audio_track_id_; StreamParser::TrackId video_track_id_; bool verifying_keyframeness_sequence_; + StrictMock<base::MockRepeatingCallback<void(Keyframeness)>> keyframeness_cb_; bool AppendData(const uint8_t* data, size_t length) { return parser_->Parse(data, length); @@ -141,11 +158,6 @@ return true; } - // Useful in single-track test media cases that need to verify - // keyframe/non-keyframe sequence in output of parse. - MOCK_METHOD0(ParsedKeyframe, void()); - MOCK_METHOD0(ParsedNonKeyframe, void()); - bool NewBuffersF(const StreamParser::BufferQueueMap& buffer_queue_map) { DecodeTimestamp lowest_end_dts = kNoDecodeTimestamp(); for (const auto& it : buffer_queue_map) { @@ -167,10 +179,9 @@ // Let single-track tests verify the sequence of keyframes/nonkeyframes. if (verifying_keyframeness_sequence_) { - if (buf->is_key_frame()) - ParsedKeyframe(); - else - ParsedNonKeyframe(); + keyframeness_cb_.Run(buf->is_key_frame() + ? Keyframeness::kKeyframe + : Keyframeness::kNonKeyframe); } } } @@ -347,8 +358,8 @@ params.detected_audio_track_count = 0; InitializeParserWithInitParametersExpectations(params); verifying_keyframeness_sequence_ = true; - EXPECT_CALL(*this, ParsedKeyframe()); - EXPECT_CALL(*this, ParsedNonKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)); ParseMP4File("bear-640x360-v-2frames_frag.mp4", 512); } @@ -366,8 +377,8 @@ EXPECT_MEDIA_LOG(DebugLog( "ISO-BMFF container metadata for video frame indicates that the frame is " "not a keyframe, but the video frame contents indicate the opposite.")); - EXPECT_CALL(*this, ParsedKeyframe()); - EXPECT_CALL(*this, ParsedNonKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)); ParseMP4File("bear-640x360-v-2frames-keyframe-is-non-sync-sample_frag.mp4", 512); } @@ -383,11 +394,11 @@ params.detected_audio_track_count = 0; InitializeParserWithInitParametersExpectations(params); verifying_keyframeness_sequence_ = true; - EXPECT_CALL(*this, ParsedKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); EXPECT_MEDIA_LOG(DebugLog( "ISO-BMFF container metadata for video frame indicates that the frame is " "a keyframe, but the video frame contents indicate the opposite.")); - EXPECT_CALL(*this, ParsedNonKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)); ParseMP4File("bear-640x360-v-2frames-nonkeyframe-is-sync-sample_frag.mp4", 512); } @@ -405,7 +416,7 @@ } TEST_F(MP4StreamParserTest, MPEG4_XHE_AAC) { - InSequence s; + InSequence s; // The keyframeness sequence matters for this test. std::set<int> audio_object_types; audio_object_types.insert(kISO_14496_3); parser_.reset(new MP4StreamParser(audio_object_types, false, false)); @@ -417,8 +428,8 @@ // This test file contains a single audio keyframe followed by 23 // non-keyframes. verifying_keyframeness_sequence_ = true; - EXPECT_CALL(*this, ParsedKeyframe()); - EXPECT_CALL(*this, ParsedNonKeyframe()).Times(23); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)).Times(23); ParseMP4File("noise-xhe-aac.mp4", 512); EXPECT_EQ(audio_decoder_config_.profile(), AudioCodecProfile::kXHE_AAC); @@ -506,8 +517,8 @@ params.detected_audio_track_count = 0; InitializeParserWithInitParametersExpectations(params); verifying_keyframeness_sequence_ = true; - EXPECT_CALL(*this, ParsedKeyframe()); - EXPECT_CALL(*this, ParsedNonKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)); ParseMP4File("bear-320x240-v-2frames_frag-hevc.mp4", 256); } @@ -525,8 +536,8 @@ EXPECT_MEDIA_LOG(DebugLog( "ISO-BMFF container metadata for video frame indicates that the frame is " "not a keyframe, but the video frame contents indicate the opposite.")); - EXPECT_CALL(*this, ParsedKeyframe()); - EXPECT_CALL(*this, ParsedNonKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)); ParseMP4File( "bear-320x240-v-2frames-keyframe-is-non-sync-sample_frag-hevc.mp4", 256); } @@ -542,11 +553,11 @@ params.detected_audio_track_count = 0; InitializeParserWithInitParametersExpectations(params); verifying_keyframeness_sequence_ = true; - EXPECT_CALL(*this, ParsedKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe)); EXPECT_MEDIA_LOG(DebugLog( "ISO-BMFF container metadata for video frame indicates that the frame is " "a keyframe, but the video frame contents indicate the opposite.")); - EXPECT_CALL(*this, ParsedNonKeyframe()); + EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)); ParseMP4File( "bear-320x240-v-2frames-nonkeyframe-is-sync-sample_frag-hevc.mp4", 256); }
diff --git a/media/gpu/h264_decoder.cc b/media/gpu/h264_decoder.cc index 59ab81d1..773c4024 100644 --- a/media/gpu/h264_decoder.cc +++ b/media/gpu/h264_decoder.cc
@@ -567,6 +567,13 @@ DVLOG(1) << "Malformed stream, no pic num " << pic_num_lx; return false; } + + if (ref_idx_lx > num_ref_idx_lX_active_minus1) { + DVLOG(1) << "Bounds mismatch: expected " << ref_idx_lx + << " <= " << num_ref_idx_lX_active_minus1; + return false; + } + ShiftRightAndInsert(ref_pic_listx, ref_idx_lx, num_ref_idx_lX_active_minus1, pic); ref_idx_lx++;
diff --git a/mojo/core/core.cc b/mojo/core/core.cc index d6092658..601b9a0 100644 --- a/mojo/core/core.cc +++ b/mojo/core/core.cc
@@ -1477,6 +1477,29 @@ return dispatcher->QueryQuota(type, limit, usage); } +MojoResult Core::SetDefaultProcessErrorHandler( + MojoDefaultProcessErrorHandler handler, + const MojoSetDefaultProcessErrorHandlerOptions* options) { + if (default_process_error_callback_ && handler) + return MOJO_RESULT_ALREADY_EXISTS; + + if (!handler) { + default_process_error_callback_.Reset(); + return MOJO_RESULT_OK; + } + + default_process_error_callback_ = base::BindRepeating( + [](MojoDefaultProcessErrorHandler handler, const std::string& error) { + MojoProcessErrorDetails details = {0}; + details.struct_size = sizeof(details); + details.error_message_length = static_cast<uint32_t>(error.size()); + details.error_message = error.c_str(); + handler(&details); + }, + handler); + return MOJO_RESULT_OK; +} + void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { base::AutoLock lock(handles_->GetLock()); handles_->GetActiveHandlesForTest(handles);
diff --git a/mojo/core/core.h b/mojo/core/core.h index eaed40c..f5ca3c8e 100644 --- a/mojo/core/core.h +++ b/mojo/core/core.h
@@ -325,6 +325,10 @@ uint64_t* limit, uint64_t* usage); + MojoResult SetDefaultProcessErrorHandler( + MojoDefaultProcessErrorHandler handler, + const MojoSetDefaultProcessErrorHandlerOptions* options); + void GetActiveHandlesForTest(std::vector<MojoHandle>* handles); private:
diff --git a/mojo/core/entrypoints.cc b/mojo/core/entrypoints.cc index 466da7e..7b342a5 100644 --- a/mojo/core/entrypoints.cc +++ b/mojo/core/entrypoints.cc
@@ -350,6 +350,12 @@ return MOJO_RESULT_UNIMPLEMENTED; } +MojoResult MojoSetDefaultProcessErrorHandlerImpl( + MojoDefaultProcessErrorHandler handler, + const MojoSetDefaultProcessErrorHandlerOptions* options) { + return g_core->SetDefaultProcessErrorHandler(handler, options); +} + } // extern "C" MojoSystemThunks g_thunks = {sizeof(MojoSystemThunks), @@ -396,7 +402,8 @@ MojoAcceptInvitationImpl, MojoSetQuotaImpl, MojoQueryQuotaImpl, - MojoShutdownImpl}; + MojoShutdownImpl, + MojoSetDefaultProcessErrorHandlerImpl}; } // namespace
diff --git a/mojo/public/c/system/functions.h b/mojo/public/c/system/functions.h index 6f47028f4..b9d60b7 100644 --- a/mojo/public/c/system/functions.h +++ b/mojo/public/c/system/functions.h
@@ -12,6 +12,7 @@ #include <stddef.h> #include <stdint.h> +#include "mojo/public/c/system/invitation.h" #include "mojo/public/c/system/system_export.h" #include "mojo/public/c/system/types.h"
diff --git a/mojo/public/c/system/invitation.h b/mojo/public/c/system/invitation.h index e63001e..f95bcc4e 100644 --- a/mojo/public/c/system/invitation.h +++ b/mojo/public/c/system/invitation.h
@@ -251,6 +251,25 @@ MOJO_STATIC_ASSERT(sizeof(struct MojoAcceptInvitationOptions) == 8, "MojoAcceptInvitationOptions has wrong size"); +// Flags passed to |MojoSetDefaultProcessErrorHandler()| via +// |MojoSetDefaultProcessErrorHandlerOptions|. +typedef uint32_t MojoSetDefaultProcessErrorHandlerFlags; + +// No flags. Default behavior. +#define MOJO_SET_DEFAULT_PROCESS_ERROR_HANDLER_FLAG_NONE \ + ((MojoSetDefaultProcessErrorHandlerFlags)0) + +// Options passed to |MojoSetDefaultProcessErrorHandler()|. +struct MOJO_ALIGNAS(8) MojoSetDefaultProcessErrorHandlerOptions { + // The size of this structure, used for versioning. + uint32_t struct_size; + + // See |MojoSetDefaultProcessErrorHandlerFlags|. + MojoSetDefaultProcessErrorHandlerFlags flags; +}; +MOJO_STATIC_ASSERT(sizeof(struct MojoSetDefaultProcessErrorHandlerOptions) == 8, + "MojoSetDefaultProcessErrorHandlerOptions has wrong size"); + #ifdef __cplusplus extern "C" { #endif @@ -266,6 +285,12 @@ uintptr_t context, const struct MojoProcessErrorDetails* details); +// Similar to above, but registered globally via +// |MojoSetDefaultProcessErrorHandler()| and invoked only for communication +// errors regarding processes NOT invited by the calling process. +typedef void (*MojoDefaultProcessErrorHandler)( + const struct MojoProcessErrorDetails* details); + // Creates a new invitation to be sent to another process. // // An invitation is used to invite another process to join this process's @@ -474,6 +499,31 @@ const struct MojoAcceptInvitationOptions* options, MojoHandle* invitation_handle); +// Registers a process-wide handler to be invoked when an error is raised on a +// connection to a peer process. Such errors can be raised if the peer process +// sends malformed data to this process. +// +// Note that this handler is only invoked for connections to processes NOT +// explicitly invited by this process. To handle errors concerning processes +// invited by this process, see the MojoProcessErrorHandler argument to +// |MojoSendInvitation()|. +// +// The general use case for this API is to be able to log or report instances of +// bad IPCs received by a client process which no real ability or authority to +// identify the source. +// +// Returns: +// |MOJO_RESULT_OK| if |handler| is successfully registered as the global +// default process error handler within the calling process. If |handler| +// is null, any registered default process error handler is removed. +// |MOJO_RESULT_ALREADY_EXISTS| if |handler| is non-null and there is already +// a registered error handler. Callers wishing to replace an existing +// handler must first call |MojoSetDefaultProcessErrorHandler()| with null +// in order to do so. +MOJO_SYSTEM_EXPORT MojoResult MojoSetDefaultProcessErrorHandler( + MojoDefaultProcessErrorHandler handler, + const struct MojoSetDefaultProcessErrorHandlerOptions* options); + #ifdef __cplusplus } // extern "C" #endif
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc index 1bf1a26..cfb7df7 100644 --- a/mojo/public/c/system/thunks.cc +++ b/mojo/public/c/system/thunks.cc
@@ -476,6 +476,12 @@ return INVOKE_THUNK(Shutdown, options); } +MojoResult MojoSetDefaultProcessErrorHandler( + MojoDefaultProcessErrorHandler handler, + const struct MojoSetDefaultProcessErrorHandlerOptions* options) { + return INVOKE_THUNK(SetDefaultProcessErrorHandler, handler, options); +} + } // extern "C" void MojoEmbedderSetSystemThunks(const MojoSystemThunks* thunks) {
diff --git a/mojo/public/c/system/thunks.h b/mojo/public/c/system/thunks.h index f3f9742a..4b41b939 100644 --- a/mojo/public/c/system/thunks.h +++ b/mojo/public/c/system/thunks.h
@@ -228,6 +228,11 @@ // Core ABI version 2 additions begin here. MojoResult (*Shutdown)(const struct MojoShutdownOptions* options); + + // Core ABI version 3 additions begin here. + MojoResult (*SetDefaultProcessErrorHandler)( + MojoDefaultProcessErrorHandler handler, + const struct MojoSetDefaultProcessErrorHandlerOptions* options); }; #pragma pack(pop)
diff --git a/mojo/public/cpp/system/BUILD.gn b/mojo/public/cpp/system/BUILD.gn index 8608e7b8..a53a40f9 100644 --- a/mojo/public/cpp/system/BUILD.gn +++ b/mojo/public/cpp/system/BUILD.gn
@@ -21,6 +21,7 @@ "file_data_source.h", "filtered_data_source.cc", "filtered_data_source.h", + "functions.cc", "functions.h", "handle.h", "handle_signal_tracker.cc",
diff --git a/mojo/public/cpp/system/functions.cc b/mojo/public/cpp/system/functions.cc new file mode 100644 index 0000000..74aee1a --- /dev/null +++ b/mojo/public/cpp/system/functions.cc
@@ -0,0 +1,36 @@ +// Copyright 2020 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 "mojo/public/cpp/system/functions.h" + +#include "base/callback.h" +#include "base/no_destructor.h" + +namespace mojo { + +namespace { + +DefaultProcessErrorHandler& GetDefaultProcessErrorHandler() { + static base::NoDestructor<DefaultProcessErrorHandler> handler; + return *handler; +} + +void HandleError(const MojoProcessErrorDetails* details) { + const DefaultProcessErrorHandler& handler = GetDefaultProcessErrorHandler(); + handler.Run( + std::string(details->error_message, details->error_message_length)); +} + +} // namespace + +void SetDefaultProcessErrorHandler(DefaultProcessErrorHandler handler) { + // Ensure any previously set handler is wiped out. + MojoSetDefaultProcessErrorHandler(nullptr, nullptr); + auto& global_handler = GetDefaultProcessErrorHandler(); + global_handler = std::move(handler); + if (global_handler) + MojoSetDefaultProcessErrorHandler(&HandleError, nullptr); +} + +} // namespace mojo
diff --git a/mojo/public/cpp/system/functions.h b/mojo/public/cpp/system/functions.h index 31edf57..4f45ece 100644 --- a/mojo/public/cpp/system/functions.h +++ b/mojo/public/cpp/system/functions.h
@@ -11,7 +11,11 @@ #ifndef MOJO_PUBLIC_CPP_SYSTEM_FUNCTIONS_H_ #define MOJO_PUBLIC_CPP_SYSTEM_FUNCTIONS_H_ +#include <string> + +#include "base/callback_forward.h" #include "mojo/public/c/system/functions.h" +#include "mojo/public/cpp/system/system_export.h" namespace mojo { @@ -21,6 +25,17 @@ return MojoGetTimeTicksNow(); } +// Sets a callback to handle communication errors regarding peer processes whose +// identity is not explicitly known by this process, i.e. processes that are +// part of the same Mojo process network but which were not invited by this +// process. +// +// This can be used to globally listen for reports of bad incoming IPCs. +using DefaultProcessErrorHandler = + base::RepeatingCallback<void(const std::string& error)>; +void MOJO_CPP_SYSTEM_EXPORT +SetDefaultProcessErrorHandler(DefaultProcessErrorHandler handler); + } // namespace mojo #endif // MOJO_PUBLIC_CPP_SYSTEM_FUNCTIONS_H_
diff --git a/mojo/public/cpp/test_support/BUILD.gn b/mojo/public/cpp/test_support/BUILD.gn index 8bde2beb..3312a37 100644 --- a/mojo/public/cpp/test_support/BUILD.gn +++ b/mojo/public/cpp/test_support/BUILD.gn
@@ -12,7 +12,6 @@ ] deps = [ - "//mojo/core/embedder", "//mojo/public/c/test_support", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system",
diff --git a/mojo/public/cpp/test_support/lib/test_utils.cc b/mojo/public/cpp/test_support/lib/test_utils.cc index 99e7f708..062106d 100644 --- a/mojo/public/cpp/test_support/lib/test_utils.cc +++ b/mojo/public/cpp/test_support/lib/test_utils.cc
@@ -10,7 +10,7 @@ #include <vector> #include "base/bind.h" -#include "mojo/core/embedder/embedder.h" +#include "base/bind_helpers.h" #include "mojo/public/cpp/system/core.h" #include "mojo/public/cpp/system/wait.h" #include "mojo/public/cpp/test_support/test_support.h" @@ -80,13 +80,12 @@ } BadMessageObserver::BadMessageObserver() : got_bad_message_(false) { - mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating( + mojo::SetDefaultProcessErrorHandler(base::BindRepeating( &BadMessageObserver::OnReportBadMessage, base::Unretained(this))); } BadMessageObserver::~BadMessageObserver() { - mojo::core::SetDefaultProcessErrorCallback( - mojo::core::ProcessErrorCallback()); + mojo::SetDefaultProcessErrorHandler(base::NullCallback()); } std::string BadMessageObserver::WaitForBadMessage() {
diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc index 5e11b9f..0716b6e 100644 --- a/net/http/http_auth_sspi_win.cc +++ b/net/http/http_auth_sspi_win.cc
@@ -547,7 +547,12 @@ if (delegation_type_ != DelegationType::kNone) context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH); - net_log.BeginEvent(NetLogEventType::AUTH_LIBRARY_INIT_SEC_CTX); + net_log.BeginEvent(NetLogEventType::AUTH_LIBRARY_INIT_SEC_CTX, [&] { + base::Value params{base::Value::Type::DICTIONARY}; + params.SetStringKey("spn", spn); + params.SetKey("flags", ContextFlagsToValue(context_flags)); + return params; + }); // This returns a token that is passed to the remote server. DWORD context_attributes = 0;
diff --git a/net/http/http_auth_sspi_win_unittest.cc b/net/http/http_auth_sspi_win_unittest.cc index 09ddf1d..bad9b9b 100644 --- a/net/http/http_auth_sspi_win_unittest.cc +++ b/net/http/http_auth_sspi_win_unittest.cc
@@ -260,6 +260,18 @@ expected = base::JSONReader::Read(R"( { + "flags": { + "delegated": false, + "mutual": false, + "value": "0x00000000" + }, + "spn": "HTTP/intranet.google.com" + } + )"); + EXPECT_EQ(expected, entries[0].params); + + expected = base::JSONReader::Read(R"( + { "context": { "authority": "Dodgy Server", "flags": {
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 6de6c8e2..0731a9a5 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -31,8 +31,11 @@ // - bulk-legacy: bulk entries preloaded before Chrome 50. // - bulk-18-weeks: bulk entries with max-age >= 18 weeks (Chrome 50-63). // - bulk-1-year: bulk entries with max-age >= 1 year (after Chrome 63). -// - public-suffix-requested: public suffixes preloaded at the owners -// request (manual). +// - public-suffix: public suffixes (e.g. TLDs or other public suffix +// list entries) preloaded at the owner's request. +// - public-suffix-requested: domains under a public suffix that have +// been preloaded at the request of the the public suffix owner (e.g. +// the registry for the TLD). // include_subdomains: (optional boolean) For backwards compatibility, this // means: // - If mode == "force-https", then apply force-https to subdomains.
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 568f998..008ac5f 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -2658,13 +2658,21 @@ // This operation involves invoking an external library which may perform disk, // IPC, and network IO as a part of its work. // -// On Posix platforms, the END phase has the following parameters. +// On Windows, the BEGIN phase has the following parameters: +// { +// "spn": <Service Principle Name>, +// "context_flags": <Integer with bitfield value> +// } +// +// The END phase has the following parameters. +// +// On Posix platforms: // { // "context": <GSSAPI Context Description>, // "status" : <GSSAPI Status if the operation failed> // } // -// On Windows, the END phase has the following parameters. +// On Windows: // { // "context": <SSPI Context Description> // "status" : <SSPI SECURITY_STATUS>
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc index dfa329e..33f341f 100644 --- a/net/quic/crypto/proof_verifier_chromium.cc +++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -459,7 +459,7 @@ verify_details_->ct_verify_result.scts, TransportSecurityState::ENABLE_EXPECT_CT_REPORTS, verify_details_->ct_verify_result.policy_compliance, - NetworkIsolationKey::Todo()); + proof_verifier_->network_isolation_key_); if (ct_requirement_status != TransportSecurityState::CT_NOT_REQUIRED) { verify_details_->ct_verify_result.policy_compliance_required = true; if (verify_details_->cert_verify_result.is_issued_by_known_root) { @@ -589,12 +589,14 @@ CTPolicyEnforcer* ct_policy_enforcer, TransportSecurityState* transport_security_state, CTVerifier* cert_transparency_verifier, - std::set<std::string> hostnames_to_allow_unknown_roots) + std::set<std::string> hostnames_to_allow_unknown_roots, + const NetworkIsolationKey& network_isolation_key) : cert_verifier_(cert_verifier), ct_policy_enforcer_(ct_policy_enforcer), transport_security_state_(transport_security_state), cert_transparency_verifier_(cert_transparency_verifier), - hostnames_to_allow_unknown_roots_(hostnames_to_allow_unknown_roots) { + hostnames_to_allow_unknown_roots_(hostnames_to_allow_unknown_roots), + network_isolation_key_(network_isolation_key) { DCHECK(cert_verifier_); DCHECK(ct_policy_enforcer_); DCHECK(transport_security_state_);
diff --git a/net/quic/crypto/proof_verifier_chromium.h b/net/quic/crypto/proof_verifier_chromium.h index 83269f3..bef7745 100644 --- a/net/quic/crypto/proof_verifier_chromium.h +++ b/net/quic/crypto/proof_verifier_chromium.h
@@ -13,6 +13,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "net/base/net_export.h" +#include "net/base/network_isolation_key.h" #include "net/cert/cert_verify_result.h" #include "net/cert/ct_verify_result.h" #include "net/cert/x509_certificate.h" @@ -74,7 +75,8 @@ CTPolicyEnforcer* ct_policy_enforcer, TransportSecurityState* transport_security_state, CTVerifier* cert_transparency_verifier, - std::set<std::string> hostnames_to_allow_unknown_roots); + std::set<std::string> hostnames_to_allow_unknown_roots, + const NetworkIsolationKey& network_isolation_key); ~ProofVerifierChromium() override; // quic::ProofVerifier interface @@ -119,6 +121,8 @@ std::set<std::string> hostnames_to_allow_unknown_roots_; + const NetworkIsolationKey network_isolation_key_; + DISALLOW_COPY_AND_ASSIGN(ProofVerifierChromium); };
diff --git a/net/quic/crypto/proof_verifier_chromium_test.cc b/net/quic/crypto/proof_verifier_chromium_test.cc index d4ce7c17..8177832 100644 --- a/net/quic/crypto/proof_verifier_chromium_test.cc +++ b/net/quic/crypto/proof_verifier_chromium_test.cc
@@ -10,6 +10,7 @@ #include "base/test/metrics/histogram_tester.h" #include "net/base/completion_once_callback.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/cert/cert_status_flags.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_log_verifier.h" @@ -201,9 +202,9 @@ MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -224,9 +225,9 @@ // verification fails. TEST_F(ProofVerifierChromiumTest, FailsIfCertFails) { MockCertVerifier dummy_verifier; - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -244,9 +245,9 @@ MockCertVerifier cert_verifier; - ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &cert_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -264,9 +265,9 @@ ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_)); MockCertVerifier cert_verifier; - ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &cert_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -282,9 +283,9 @@ // signature fails. TEST_F(ProofVerifierChromiumTest, FailsIfSignatureFails) { FailsTestCertVerifier cert_verifier; - ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &cert_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -307,9 +308,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -338,9 +339,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -375,9 +376,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -416,9 +417,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -454,9 +455,9 @@ dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, ERR_CERT_DATE_INVALID); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -482,9 +483,9 @@ base::Time::Now() + base::TimeDelta::FromSeconds(1000); transport_security_state_.AddHSTS(kTestHostname, expiry, true); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -509,9 +510,9 @@ transport_security_state_.EnableStaticPinsForTesting(); ScopedTransportSecurityStateSource scoped_security_state_source; - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -542,9 +543,9 @@ transport_security_state_.EnableStaticPinsForTesting(); ScopedTransportSecurityStateSource scoped_security_state_source; - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {kCTAndPKPHost}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {kCTAndPKPHost}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -582,9 +583,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -628,9 +629,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -673,9 +674,9 @@ { MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {kTestHostname}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -692,9 +693,9 @@ dummy_result_.is_issued_by_known_root = true; MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -724,9 +725,9 @@ MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {kTestHostname}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -764,9 +765,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -802,9 +803,9 @@ { MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {kTestHostname}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -823,9 +824,9 @@ dummy_result_.is_issued_by_known_root = true; MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -860,9 +861,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -895,9 +896,9 @@ .WillRepeatedly( Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS)); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -919,9 +920,9 @@ MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -941,9 +942,9 @@ MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {kTestHostname}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {kTestHostname}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -966,9 +967,9 @@ MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {""}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {""}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback); @@ -990,9 +991,9 @@ MockCertVerifier dummy_verifier; dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK); - ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_, - &transport_security_state_, - ct_verifier_.get(), {}); + ProofVerifierChromium proof_verifier( + &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_, + ct_verifier_.get(), {}, NetworkIsolationKey()); std::unique_ptr<DummyProofVerifierCallback> callback( new DummyProofVerifierCallback);
diff --git a/net/quic/crypto_test_utils_chromium.cc b/net/quic/crypto_test_utils_chromium.cc index f284f7c4..256dc0e 100644 --- a/net/quic/crypto_test_utils_chromium.cc +++ b/net/quic/crypto_test_utils_chromium.cc
@@ -11,6 +11,7 @@ #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/cert/cert_status_flags.h" #include "net/cert/cert_verifier.h" @@ -53,7 +54,8 @@ ct_policy_enforcer.get(), transport_security_state.get(), cert_transparency_verifier.get(), - {"test.example.com"}), + {"test.example.com"}, + NetworkIsolationKey()), cert_verifier_(std::move(cert_verifier)), transport_security_state_(std::move(transport_security_state)), cert_transparency_verifier_(std::move(cert_transparency_verifier)),
diff --git a/net/quic/platform/impl/quic_default_proof_providers_impl.cc b/net/quic/platform/impl/quic_default_proof_providers_impl.cc index 28ec276..bbe4a70 100644 --- a/net/quic/platform/impl/quic_default_proof_providers_impl.cc +++ b/net/quic/platform/impl/quic_default_proof_providers_impl.cc
@@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "net/base/network_isolation_key.h" #include "net/cert/cert_verifier.h" #include "net/cert/ct_log_verifier.h" #include "net/cert/ct_policy_enforcer.h" @@ -64,7 +65,10 @@ &ct_policy_enforcer_, &transport_security_state_, &ct_verifier_, - UnknownRootAllowlistForHost(host)), + UnknownRootAllowlistForHost(host), + // Fine to use an empty NetworkIsolationKey + // here, since this isn't used in Chromium. + net::NetworkIsolationKey()), cert_verifier_(std::move(cert_verifier)) {} private:
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index eb9dea40..b82a569 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -2264,7 +2264,8 @@ std::make_unique<ProofVerifierChromium>( cert_verifier_, ct_policy_enforcer_, transport_security_state_, cert_transparency_verifier_, - HostsFromOrigins(params_.origins_to_force_quic_on)), + HostsFromOrigins(params_.origins_to_force_quic_on), + actual_network_isolation_key), this); quic::QuicCryptoClientConfig* crypto_config = crypto_config_owner->config();
diff --git a/net/quic/quic_transport_client.cc b/net/quic/quic_transport_client.cc index b93c8ba..2d0415ba 100644 --- a/net/quic/quic_transport_client.cc +++ b/net/quic/quic_transport_client.cc
@@ -61,7 +61,8 @@ context->transport_security_state(), context->cert_transparency_verifier(), std::set<std::string>(HostsFromOrigins( - quic_context_->params()->origins_to_force_quic_on))), + quic_context_->params()->origins_to_force_quic_on)), + isolation_key_), /* session_cache */ nullptr) {} QuicTransportClient::~QuicTransportClient() = default;
diff --git a/net/reporting/reporting_browsing_data_remover.cc b/net/reporting/reporting_browsing_data_remover.cc index 310242a..084b8d6c 100644 --- a/net/reporting/reporting_browsing_data_remover.cc +++ b/net/reporting/reporting_browsing_data_remover.cc
@@ -15,7 +15,7 @@ // static void ReportingBrowsingDataRemover::RemoveBrowsingData( ReportingCache* cache, - int data_type_mask, + uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { if ((data_type_mask & DATA_TYPE_REPORTS) != 0) { std::vector<const ReportingReport*> all_reports; @@ -42,8 +42,9 @@ } // static -void ReportingBrowsingDataRemover::RemoveAllBrowsingData(ReportingCache* cache, - int data_type_mask) { +void ReportingBrowsingDataRemover::RemoveAllBrowsingData( + ReportingCache* cache, + uint64_t data_type_mask) { if ((data_type_mask & DATA_TYPE_REPORTS) != 0) { cache->RemoveAllReports( ReportingReport::Outcome::ERASED_BROWSING_DATA_REMOVED);
diff --git a/net/reporting/reporting_browsing_data_remover.h b/net/reporting/reporting_browsing_data_remover.h index ce3df31f..f4a9e2b 100644 --- a/net/reporting/reporting_browsing_data_remover.h +++ b/net/reporting/reporting_browsing_data_remover.h
@@ -32,13 +32,14 @@ // persisted, it will need to be cleared as well. static void RemoveBrowsingData( ReportingCache* cache, - int data_type_mask, + uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter); // Like RemoveBrowsingData except removes data for all origins without a // filter. Allows slight optimization over passing an always-true filter to // RemoveBrowsingData. - static void RemoveAllBrowsingData(ReportingCache* cache, int data_type_mask); + static void RemoveAllBrowsingData(ReportingCache* cache, + uint64_t data_type_mask); private: DISALLOW_IMPLICIT_CONSTRUCTORS(ReportingBrowsingDataRemover);
diff --git a/net/reporting/reporting_browsing_data_remover_unittest.cc b/net/reporting/reporting_browsing_data_remover_unittest.cc index 5f4b83b7..687bf5a 100644 --- a/net/reporting/reporting_browsing_data_remover_unittest.cc +++ b/net/reporting/reporting_browsing_data_remover_unittest.cc
@@ -24,7 +24,7 @@ void RemoveBrowsingData(bool remove_reports, bool remove_clients, std::string host) { - int data_type_mask = 0; + uint64_t data_type_mask = 0; if (remove_reports) data_type_mask |= ReportingBrowsingDataRemover::DATA_TYPE_REPORTS; if (remove_clients)
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc index 2a410343..2467f14 100644 --- a/net/reporting/reporting_service.cc +++ b/net/reporting/reporting_service.cc
@@ -101,7 +101,7 @@ NetworkIsolationKey::Todo(), url, std::move(header_value))); } - void RemoveBrowsingData(int data_type_mask, + void RemoveBrowsingData(uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override { DoOrBacklogTask(base::BindOnce(&ReportingServiceImpl::DoRemoveBrowsingData, @@ -109,7 +109,7 @@ origin_filter)); } - void RemoveAllBrowsingData(int data_type_mask) override { + void RemoveAllBrowsingData(uint64_t data_type_mask) override { DoOrBacklogTask( base::BindOnce(&ReportingServiceImpl::DoRemoveAllBrowsingData, base::Unretained(this), data_type_mask)); @@ -174,14 +174,14 @@ } void DoRemoveBrowsingData( - int data_type_mask, + uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { DCHECK(initialized_); ReportingBrowsingDataRemover::RemoveBrowsingData( context_->cache(), data_type_mask, origin_filter); } - void DoRemoveAllBrowsingData(int data_type_mask) { + void DoRemoveAllBrowsingData(uint64_t data_type_mask) { DCHECK(initialized_); ReportingBrowsingDataRemover::RemoveAllBrowsingData(context_->cache(), data_type_mask);
diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h index 233608c..e215236 100644 --- a/net/reporting/reporting_service.h +++ b/net/reporting/reporting_service.h
@@ -68,12 +68,12 @@ // Removes browsing data from the Reporting system. See // ReportingBrowsingDataRemover for more details. virtual void RemoveBrowsingData( - int data_type_mask, + uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) = 0; // Like RemoveBrowsingData except removes data for all origins without a // filter. - virtual void RemoveAllBrowsingData(int data_type_mask) = 0; + virtual void RemoveAllBrowsingData(uint64_t data_type_mask) = 0; // Shuts down the Reporting service so that no new headers or reports are // processed, and pending uploads are cancelled.
diff --git a/net/reporting/reporting_test_util.cc b/net/reporting/reporting_test_util.cc index 47ebd724..fc3b015 100644 --- a/net/reporting/reporting_test_util.cc +++ b/net/reporting/reporting_test_util.cc
@@ -334,12 +334,12 @@ } void TestReportingService::RemoveBrowsingData( - int data_type_mask, + uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { NOTREACHED(); } -void TestReportingService::RemoveAllBrowsingData(int data_type_mask) { +void TestReportingService::RemoveAllBrowsingData(uint64_t data_type_mask) { NOTREACHED(); }
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h index 5f7c990..e58f4491 100644 --- a/net/reporting/reporting_test_util.h +++ b/net/reporting/reporting_test_util.h
@@ -320,10 +320,10 @@ void ProcessHeader(const GURL& url, const std::string& header_value) override; void RemoveBrowsingData( - int data_type_mask, + uint64_t data_type_mask, const base::RepeatingCallback<bool(const GURL&)>& origin_filter) override; - void RemoveAllBrowsingData(int data_type_mask) override; + void RemoveAllBrowsingData(uint64_t data_type_mask) override; void OnShutdown() override;
diff --git a/net/url_request/url_request_quic_unittest.cc b/net/url_request/url_request_quic_unittest.cc index 6df77e8..fb8e2f6 100644 --- a/net/url_request/url_request_quic_unittest.cc +++ b/net/url_request/url_request_quic_unittest.cc
@@ -11,11 +11,15 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/test/bind_test_util.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "net/base/features.h" #include "net/base/isolation_info.h" #include "net/base/load_timing_info.h" #include "net/base/network_delegate.h" +#include "net/base/network_isolation_key.h" +#include "net/cert/ct_policy_enforcer.h" +#include "net/cert/ct_policy_status.h" #include "net/cert/mock_cert_verifier.h" #include "net/dns/mapped_host_resolver.h" #include "net/dns/mock_host_resolver.h" @@ -64,6 +68,53 @@ const char kIndexBodyValue[] = "Hello from QUIC Server"; const int kIndexStatus = 200; +class MockCTPolicyEnforcerNonCompliant : public CTPolicyEnforcer { + public: + MockCTPolicyEnforcerNonCompliant() = default; + ~MockCTPolicyEnforcerNonCompliant() override = default; + + ct::CTPolicyCompliance CheckCompliance( + X509Certificate* cert, + const ct::SCTList& verified_scts, + const NetLogWithSource& net_log) override { + return ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS; + } +}; + +// An ExpectCTReporter that records the number of times OnExpectCTFailed() was +// called. +class MockExpectCTReporter : public TransportSecurityState::ExpectCTReporter { + public: + MockExpectCTReporter() = default; + ~MockExpectCTReporter() override = default; + + void OnExpectCTFailed( + const HostPortPair& host_port_pair, + const GURL& report_uri, + base::Time expiration, + const X509Certificate* validated_certificate_chain, + const X509Certificate* served_certificate_chain, + const SignedCertificateTimestampAndStatusList& + signed_certificate_timestamps, + const NetworkIsolationKey& network_isolation_key) override { + num_failures_++; + report_uri_ = report_uri; + network_isolation_key_ = network_isolation_key; + } + + int num_failures() const { return num_failures_; } + const GURL& report_uri() const { return report_uri_; } + const NetworkIsolationKey& network_isolation_key() const { + return network_isolation_key_; + } + + private: + int num_failures_ = 0; + + GURL report_uri_; + NetworkIsolationKey network_isolation_key_; +}; + class URLRequestQuicTest : public TestWithTaskEnvironment, public ::testing::WithParamInterface<quic::ParsedQuicVersion> { @@ -78,8 +129,7 @@ verify_result.verified_cert = ImportCertFromFile( GetTestCertsDirectory(), "quic-chain.pem"); cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(), - "test.example.com", verify_result, - OK); + kTestServerHost, verify_result, OK); // To simplify the test, and avoid the race with the HTTP request, we force // QUIC for these requests. context_->set_quic_context(&quic_context_); @@ -92,6 +142,8 @@ context_->set_http_network_session_params(std::move(params)); context_->set_cert_verifier(&cert_verifier_); context_->set_net_log(&net_log_); + transport_security_state_.SetExpectCTReporter(&expect_ct_reporter_); + context_->set_transport_security_state(&transport_security_state_); } void TearDown() override { @@ -108,6 +160,10 @@ context_->set_network_delegate(network_delegate); } + // Can be used to modify |context_|. Only safe to modify before Init() is + // called. + TestURLRequestContext* context() { return context_.get(); } + // Initializes the TestURLRequestContext |context_|. void Init() { context_->Init(); } @@ -155,6 +211,12 @@ quic::ParsedQuicVersion version() { return GetParam(); } + MockExpectCTReporter* expect_ct_reporter() { return &expect_ct_reporter_; } + + TransportSecurityState* transport_security_state() { + return &transport_security_state_; + } + protected: // Returns a fully-qualified URL for |path| on the test server. std::string UrlFromPath(base::StringPiece path) { @@ -219,6 +281,9 @@ return path.MaybeAsASCII(); } + MockExpectCTReporter expect_ct_reporter_; + TransportSecurityState transport_security_state_; + std::unique_ptr<MappedHostResolver> host_resolver_; std::unique_ptr<QuicSimpleServer> server_; std::unique_ptr<TestURLRequestContext> context_; @@ -637,4 +702,50 @@ EXPECT_EQ(OK, delegate.request_status()); } +// Tests that if there's an Expect-CT failure at the QUIC layer, a report is +// generated. +TEST_P(URLRequestQuicTest, ExpectCT) { + // Expect-CT seems not to supported for quic::PROTOCOL_TLS1_3 handshakes. + // TODO(https://crbug.com/1090838): Remove this early exit once that is fixed. + if (GetParam().handshake_protocol == quic::PROTOCOL_TLS1_3) { + // Need this to avoid a DCHECK. + Init(); + return; + } + + TransportSecurityState::SetRequireCTForTesting(true); + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures( + // enabled_features + {features::kPartitionConnectionsByNetworkIsolationKey, + features::kPartitionHttpServerPropertiesByNetworkIsolationKey, + features::kPartitionSSLSessionsByNetworkIsolationKey}, + // disabled_features + {}); + + MockCTPolicyEnforcerNonCompliant ct_enforcer; + context()->set_ct_policy_enforcer(&ct_enforcer); + Init(); + + GURL report_uri("https://report.test/"); + transport_security_state()->AddExpectCT( + kTestServerHost, base::Time::Now() + base::TimeDelta::FromDays(1), + true /* enforce */, report_uri); + + base::RunLoop run_loop; + TestDelegate delegate; + std::unique_ptr<URLRequest> request = + CreateRequest(GURL(UrlFromPath(kHelloPath)), DEFAULT_PRIORITY, &delegate); + IsolationInfo isolation_info = IsolationInfo::CreateTransient(); + request->set_isolation_info(isolation_info); + request->Start(); + delegate.RunUntilComplete(); + + EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate.request_status()); + ASSERT_EQ(1, expect_ct_reporter()->num_failures()); + EXPECT_EQ(report_uri, expect_ct_reporter()->report_uri()); + EXPECT_EQ(isolation_info.network_isolation_key(), + expect_ct_reporter()->network_isolation_key()); +} + } // namespace net
diff --git a/services/network/p2p/socket_tcp.cc b/services/network/p2p/socket_tcp.cc index 385433b..f231358 100644 --- a/services/network/p2p/socket_tcp.cc +++ b/services/network/p2p/socket_tcp.cc
@@ -14,6 +14,7 @@ #include "jingle/glue/fake_ssl_client_socket.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" #include "net/socket/ssl_client_socket.h" @@ -106,7 +107,9 @@ socket_ = proxy_resolving_socket_factory_->CreateSocket( GURL("https://" + dest_host_port_pair.ToString()), - IsTlsClientSocket(type_)); + // TODO(https://crbug.com/1021661): Pass in a non-empty + // NetworkIsolationKey here. + net::NetworkIsolationKey::Todo(), IsTlsClientSocket(type_)); if (IsPseudoTlsClientSocket(type_)) { socket_ =
diff --git a/services/network/proxy_resolving_client_socket.cc b/services/network/proxy_resolving_client_socket.cc index fc60080..c1fe8951 100644 --- a/services/network/proxy_resolving_client_socket.cc +++ b/services/network/proxy_resolving_client_socket.cc
@@ -38,10 +38,12 @@ net::HttpNetworkSession* network_session, const net::CommonConnectJobParams* common_connect_job_params, const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, bool use_tls) : network_session_(network_session), common_connect_job_params_(common_connect_job_params), url_(url), + network_isolation_key_(network_isolation_key), use_tls_(use_tls), net_log_(net::NetLogWithSource::Make(network_session_->net_log(), net::NetLogSourceType::SOCKET)), @@ -245,8 +247,8 @@ // // TODO(https://crbug.com/1023439): Pass along a NetworkIsolationKey. return network_session_->proxy_resolution_service()->ResolveProxy( - url_, net::HttpRequestHeaders::kPostMethod, - net::NetworkIsolationKey::Todo(), &proxy_info_, + url_, net::HttpRequestHeaders::kPostMethod, network_isolation_key_, + &proxy_info_, base::BindOnce(&ProxyResolvingClientSocket::OnIOComplete, base::Unretained(this)), &proxy_resolve_request_, net_log_); @@ -299,7 +301,7 @@ use_tls_, net::HostPortPair::FromURL(url_), proxy_info_.proxy_server(), proxy_annotation_tag, &ssl_config, &ssl_config, true /* force_tunnel */, net::PRIVACY_MODE_DISABLED, net::OnHostResolutionCallback(), - net::MAXIMUM_PRIORITY, net::SocketTag(), net::NetworkIsolationKey(), + net::MAXIMUM_PRIORITY, net::SocketTag(), network_isolation_key_, false /* disable_secure_dns */, common_connect_job_params_, this); return connect_job_->Connect(); }
diff --git a/services/network/proxy_resolving_client_socket.h b/services/network/proxy_resolving_client_socket.h index 07271b5..6ce2a2bd 100644 --- a/services/network/proxy_resolving_client_socket.h +++ b/services/network/proxy_resolving_client_socket.h
@@ -17,6 +17,7 @@ #include "base/memory/weak_ptr.h" #include "net/base/host_port_pair.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/log/net_log_with_source.h" #include "net/proxy_resolution/proxy_info.h" #include "net/proxy_resolution/proxy_resolution_service.h" @@ -31,6 +32,7 @@ class HttpAuthController; class HttpResponseInfo; class HttpNetworkSession; +class NetworkIsolationKey; class ProxyResolutionRequest; } // namespace net @@ -55,6 +57,7 @@ net::HttpNetworkSession* network_session, const net::CommonConnectJobParams* common_connect_job_params, const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, bool use_tls); ~ProxyResolvingClientSocket() override; @@ -132,6 +135,7 @@ std::unique_ptr<net::ProxyResolutionRequest> proxy_resolve_request_; net::ProxyInfo proxy_info_; const GURL url_; + const net::NetworkIsolationKey network_isolation_key_; const bool use_tls_; net::NetLogWithSource net_log_;
diff --git a/services/network/proxy_resolving_client_socket_factory.cc b/services/network/proxy_resolving_client_socket_factory.cc index 0d00e6d..47d01a3 100644 --- a/services/network/proxy_resolving_client_socket_factory.cc +++ b/services/network/proxy_resolving_client_socket_factory.cc
@@ -76,6 +76,7 @@ std::unique_ptr<ProxyResolvingClientSocket> ProxyResolvingClientSocketFactory::CreateSocket( const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, bool use_tls) { // |request_context|'s HttpAuthCache might have updates. For example, a user // might have since entered proxy credentials. Clear the http auth of @@ -96,7 +97,8 @@ ->http_auth_cache(); network_session_->http_auth_cache()->CopyProxyEntriesFrom(*other_auth_cache); return std::make_unique<ProxyResolvingClientSocket>( - network_session_.get(), common_connect_job_params_.get(), url, use_tls); + network_session_.get(), common_connect_job_params_.get(), url, + network_isolation_key, use_tls); } } // namespace network
diff --git a/services/network/proxy_resolving_client_socket_factory.h b/services/network/proxy_resolving_client_socket_factory.h index 9192d57ea..01410d9 100644 --- a/services/network/proxy_resolving_client_socket_factory.h +++ b/services/network/proxy_resolving_client_socket_factory.h
@@ -16,6 +16,7 @@ namespace net { struct CommonConnectJobParams; class HttpNetworkSession; +class NetworkIsolationKey; class URLRequestContext; } // namespace net @@ -37,11 +38,20 @@ // doesn't need to explicitly sanitize the url, any sensitive data (like // embedded usernames and passwords), and local data (i.e. reference fragment) // will be sanitized by net::ProxyService::ResolveProxyHelper() before the url - // is disclosed to the proxy. If |use_tls|, TLS connect will be used in - // addition to TCP connect. The URLRequestContext's SSL configurations will be - // respected when establishing a TLS connection. - std::unique_ptr<ProxyResolvingClientSocket> CreateSocket(const GURL& url, - bool use_tls); + // is disclosed to the proxy. + // + // |network_isolation_key| indicates the network shard to use for storing + // shared network state (DNS cache entries, shared H2/QUIC proxy connections, + // etc). Proxy connections will only be shared with other + // ProxyResolvingClientSockets, not with standards HTTP/HTTPS requests. + // + // If |use_tls| is true, TLS connect will be used in addition to TCP connect. + // The URLRequestContext's SSL configurations will be respected when + // establishing a TLS connection. + std::unique_ptr<ProxyResolvingClientSocket> CreateSocket( + const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, + bool use_tls); const net::HttpNetworkSession* network_session() const { return network_session_.get();
diff --git a/services/network/proxy_resolving_client_socket_unittest.cc b/services/network/proxy_resolving_client_socket_unittest.cc index 84a404f..c994133 100644 --- a/services/network/proxy_resolving_client_socket_unittest.cc +++ b/services/network/proxy_resolving_client_socket_unittest.cc
@@ -13,17 +13,21 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/threading/thread_task_runner_handle.h" +#include "net/base/features.h" #include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" +#include "net/http/http_proxy_connect_job.h" #include "net/proxy_resolution/configured_proxy_resolution_service.h" #include "net/proxy_resolution/mock_proxy_resolver.h" #include "net/proxy_resolution/proxy_config_service_fixed.h" #include "net/proxy_resolution/proxy_config_with_annotation.h" #include "net/socket/client_socket_pool_manager.h" #include "net/socket/socket_test_util.h" +#include "net/spdy/spdy_test_util_common.h" #include "net/test/gtest_util.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_test_util.h" @@ -44,7 +48,7 @@ net::ConfiguredProxyResolutionService::CreateFixedFromPacResult( pac_result, TRAFFIC_ANNOTATION_FOR_TESTS)); // net::MockHostResolver maps all hosts to localhost. - auto host_resolver = std::make_unique<net::MockHostResolver>(); + auto host_resolver = std::make_unique<net::MockCachingHostResolver>(); context_storage_.set_host_resolver(std::move(host_resolver)); set_client_socket_factory(client_socket_factory); Init(); @@ -61,7 +65,14 @@ ProxyResolvingClientSocketTest() : context_with_proxy_("PROXY bad:99; PROXY maybe:80; DIRECT", &mock_client_socket_factory_), - use_tls_(GetParam()) {} + use_tls_(GetParam()) { + feature_list_.InitWithFeatures( + // enabled_features + {net::features::kPartitionConnectionsByNetworkIsolationKey, + net::features::kSplitHostCacheByNetworkIsolationKey}, + // disabled_features + {}); + } ~ProxyResolvingClientSocketTest() override {} @@ -72,6 +83,7 @@ } base::test::TaskEnvironment task_environment_; + base::test::ScopedFeatureList feature_list_; TestURLRequestContextWithProxy context_with_proxy_; net::MockClientSocketFactory mock_client_socket_factory_; const bool use_tls_; @@ -81,6 +93,183 @@ ProxyResolvingClientSocketTest, ::testing::Bool()); +// Checks the correct NetworkIsolationKey is used for host resolution in the +// case no proxy is in use. +TEST_P(ProxyResolvingClientSocketTest, NetworkIsolationKeyDirect) { + // This deliberately uses a different origin than the one being connected to. + url::Origin kNetworkIsolationKeyOrigin = + url::Origin::Create(GURL("https://foopy.test")); + net::NetworkIsolationKey kNetworkIsolationKey( + kNetworkIsolationKeyOrigin /* top_frame_origin */, + kNetworkIsolationKeyOrigin /* frame_origin */); + + TestURLRequestContextWithProxy url_request_context( + "DIRECT", &mock_client_socket_factory_); + const GURL kDestination("https://dest.test/"); + net::StaticSocketDataProvider socket_data; + mock_client_socket_factory_.AddSocketDataProvider(&socket_data); + net::SSLSocketDataProvider ssl_data(net::ASYNC, net::OK); + mock_client_socket_factory_.AddSSLSocketDataProvider(&ssl_data); + + ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( + &url_request_context); + std::unique_ptr<ProxyResolvingClientSocket> socket = + proxy_resolving_socket_factory.CreateSocket( + kDestination, kNetworkIsolationKey, use_tls_); + net::TestCompletionCallback callback; + int status = socket->Connect(callback.callback()); + EXPECT_THAT(callback.GetResult(status), net::test::IsOk()); + + // Check that the URL in kDestination is in the HostCache, with + // kNetworkIsolationInfo. + const net::HostPortPair kDestinationHostPortPair = + net::HostPortPair::FromURL(kDestination); + net::HostResolver::ResolveHostParameters params; + params.source = net::HostResolverSource::LOCAL_ONLY; + std::unique_ptr<net::HostResolver::ResolveHostRequest> request1 = + url_request_context.host_resolver()->CreateRequest( + kDestinationHostPortPair, kNetworkIsolationKey, + net::NetLogWithSource(), params); + net::TestCompletionCallback callback2; + int result = request1->Start(callback2.callback()); + EXPECT_EQ(net::OK, callback2.GetResult(result)); + + // Check that the hostname is not in the DNS cache for other possible NIKs. + const url::Origin kDestinationOrigin = url::Origin::Create(kDestination); + const net::NetworkIsolationKey kOtherNiks[] = { + net::NetworkIsolationKey(), + net::NetworkIsolationKey(kDestinationOrigin /* top_frame_origin */, + kDestinationOrigin /* frame_origin */)}; + for (const auto& other_nik : kOtherNiks) { + std::unique_ptr<net::HostResolver::ResolveHostRequest> request2 = + url_request_context.host_resolver()->CreateRequest( + kDestinationHostPortPair, other_nik, net::NetLogWithSource(), + params); + net::TestCompletionCallback callback3; + int result = request2->Start(callback3.callback()); + EXPECT_EQ(net::ERR_NAME_NOT_RESOLVED, callback3.GetResult(result)); + } +} + +// Checks the correct NetworkIsolationKey is used for host resolution in the +// case an H2 proxy is in use. In the non-H2 proxy case, the NetworkIsolationKey +// makes little difference, but in the H2 case, it affects which requests use +// the same session. Unlike other tests, this test creates a +// ProxyResolvingClientSocket instead of using the factory class, because it +// uses SpdySessionDependencies to create a NetworkSession configured to test +// H2. +TEST_P(ProxyResolvingClientSocketTest, NetworkIsolationKeyWithH2Proxy) { + // Don't bother running this test in the SSL case - it's complicated enough + // without it, and testing HTTPS on top of H2 provides minimal value, since + // SSL is mocked out anyways and there are other tests that cover it on top of + // HTTP/1.x tunnels. + if (GetParam() == true) + return; + net::SpdySessionDependencies session_deps; + session_deps.proxy_resolution_service = + net::ConfiguredProxyResolutionService::CreateFixedFromPacResult( + "HTTPS proxy.test:80", TRAFFIC_ANNOTATION_FOR_TESTS); + std::unique_ptr<net::HttpNetworkSession> http_network_session = + net::SpdySessionDependencies::SpdyCreateSession(&session_deps); + + net::NetworkIsolationKey kNetworkIsolationKey1 = + net::NetworkIsolationKey::CreateTransient(); + net::NetworkIsolationKey kNetworkIsolationKey2 = + net::NetworkIsolationKey::CreateTransient(); + + const GURL kDestination1("https://dest1.test/"); + const GURL kDestination2("https://dest2.test/"); + const GURL kDestination3("https://dest3.test/"); + + // A tunnel to kDestination1 and kDestination3 is requested using + // kNetworkIsolationKey1, so they should use the same H2 session, and a tunnel + // to kDestination2 is requested using kNetworkIsolationKey2, which should use + // a different session. + net::SpdyTestUtil spdy_util1; + spdy::SpdySerializedFrame connect_dest1(spdy_util1.ConstructSpdyConnect( + nullptr, 0, 1, net::HttpProxyConnectJob::kH2QuicTunnelPriority, + net::HostPortPair::FromURL(kDestination1))); + spdy::SpdySerializedFrame connect_dest1_resp( + spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1)); + spdy::SpdySerializedFrame connect_dest3(spdy_util1.ConstructSpdyConnect( + nullptr, 0, 3, net::HttpProxyConnectJob::kH2QuicTunnelPriority, + net::HostPortPair::FromURL(kDestination3))); + spdy::SpdySerializedFrame connect_dest3_resp( + spdy_util1.ConstructSpdyGetReply(nullptr, 0, 3)); + + net::MockWrite spdy_writes[] = { + net::CreateMockWrite(connect_dest1, 0), + net::CreateMockWrite(connect_dest3, 2), + }; + + net::MockRead spdy_reads[] = { + net::CreateMockRead(connect_dest1_resp, 1, net::ASYNC), + net::CreateMockRead(connect_dest3_resp, 3, net::ASYNC), + net::MockRead(net::SYNCHRONOUS, 0, 4), + }; + + net::SequencedSocketData socket_data(spdy_reads, spdy_writes); + session_deps.socket_factory->AddSocketDataProvider(&socket_data); + net::SSLSocketDataProvider ssl_data(net::ASYNC, net::OK); + ssl_data.next_proto = net::kProtoHTTP2; + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_data); + + net::SpdyTestUtil spdy_util2; + spdy::SpdySerializedFrame connect_dest2(spdy_util2.ConstructSpdyConnect( + nullptr, 0, 1, net::HttpProxyConnectJob::kH2QuicTunnelPriority, + net::HostPortPair::FromURL(kDestination2))); + spdy::SpdySerializedFrame connect_dest2_resp( + spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1)); + + net::MockWrite spdy_writes2[] = { + net::CreateMockWrite(connect_dest2, 0), + }; + + net::MockRead spdy_reads2[] = { + net::CreateMockRead(connect_dest2_resp, 1, net::ASYNC), + net::MockRead(net::SYNCHRONOUS, 0, 2), + }; + + net::SequencedSocketData socket_data2(spdy_reads2, spdy_writes2); + session_deps.socket_factory->AddSocketDataProvider(&socket_data2); + net::SSLSocketDataProvider ssl_data2(net::ASYNC, net::OK); + ssl_data2.next_proto = net::kProtoHTTP2; + session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_data2); + + // Connect to kDestination1 using kNetworkIsolationKey1. It should use a new + // H2 session. + net::CommonConnectJobParams common_connect_job_params = + http_network_session->CreateCommonConnectJobParams(); + ProxyResolvingClientSocket socket1( + http_network_session.get(), &common_connect_job_params, kDestination1, + kNetworkIsolationKey1, false /* use_tls */); + net::TestCompletionCallback callback1; + int result = socket1.Connect(callback1.callback()); + EXPECT_THAT(callback1.GetResult(result), net::test::IsOk()); + + // Connect to kDestination2 using kNetworkIsolationKey2. It should use a new + // H2 session. + ProxyResolvingClientSocket socket2( + http_network_session.get(), &common_connect_job_params, kDestination2, + kNetworkIsolationKey2, false /* use_tls */); + net::TestCompletionCallback callback2; + result = socket2.Connect(callback2.callback()); + EXPECT_THAT(callback2.GetResult(result), net::test::IsOk()); + EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); + EXPECT_TRUE(socket_data2.AllReadDataConsumed()); + + // Connect to kDestination3 using kNetworkIsolationKey1. It should reuse the + // first H2 session. + ProxyResolvingClientSocket socket3( + http_network_session.get(), &common_connect_job_params, kDestination3, + kNetworkIsolationKey1, false /* use_tls */); + net::TestCompletionCallback callback3; + result = socket3.Connect(callback3.callback()); + EXPECT_THAT(callback3.GetResult(result), net::test::IsOk()); + EXPECT_TRUE(socket_data.AllWriteDataConsumed()); + EXPECT_TRUE(socket_data.AllReadDataConsumed()); +} + // Tests that the global socket pool limit // (ClientSocketPoolManager::max_sockets_per_group) doesn't apply to this // type of sockets. @@ -112,7 +301,8 @@ std::vector<std::unique_ptr<ProxyResolvingClientSocket>> sockets; for (int i = 0; i < kNumSockets; ++i) { std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_THAT(callback.GetResult(status), net::test::IsOk()); @@ -153,7 +343,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status); @@ -203,7 +394,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status); @@ -238,7 +430,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status); @@ -305,7 +498,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status); @@ -369,7 +563,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status); @@ -405,7 +600,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_THAT(callback.GetResult(status), @@ -483,7 +679,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_THAT(callback.GetResult(status), net::test::IsOk()); @@ -540,7 +737,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_THAT(callback.GetResult(status), net::test::IsOk()); @@ -598,7 +796,8 @@ mock_client_socket_factory_.AddSSLSocketDataProvider(&ssl_socket); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_THAT(callback.GetResult(status), net::test::IsOk()); @@ -638,7 +837,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); @@ -666,7 +866,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); @@ -698,7 +899,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(url, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + url, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status); @@ -742,7 +944,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(url, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + url, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; EXPECT_EQ(net::ERR_IO_PENDING, socket->Connect(callback.callback())); socket.reset(); @@ -776,7 +979,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( context.get()); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); status = callback.GetResult(status); @@ -868,7 +1072,8 @@ ProxyResolvingClientSocketFactory proxy_resolving_socket_factory( &context_with_proxy_); std::unique_ptr<ProxyResolvingClientSocket> socket = - proxy_resolving_socket_factory.CreateSocket(kDestination, use_tls_); + proxy_resolving_socket_factory.CreateSocket( + kDestination, net::NetworkIsolationKey(), use_tls_); net::TestCompletionCallback callback; int status = socket->Connect(callback.callback()); EXPECT_EQ(net::ERR_IO_PENDING, status);
diff --git a/services/network/proxy_resolving_socket_factory_mojo.cc b/services/network/proxy_resolving_socket_factory_mojo.cc index 2d673a7..059a488 100644 --- a/services/network/proxy_resolving_socket_factory_mojo.cc +++ b/services/network/proxy_resolving_socket_factory_mojo.cc
@@ -25,13 +25,14 @@ void ProxyResolvingSocketFactoryMojo::CreateProxyResolvingSocket( const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, mojom::ProxyResolvingSocketOptionsPtr options, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojo::PendingReceiver<mojom::ProxyResolvingSocket> receiver, mojo::PendingRemote<mojom::SocketObserver> observer, CreateProxyResolvingSocketCallback callback) { - std::unique_ptr<net::StreamSocket> net_socket = - factory_impl_.CreateSocket(url, options && options->use_tls); + std::unique_ptr<net::StreamSocket> net_socket = factory_impl_.CreateSocket( + url, network_isolation_key, options && options->use_tls); if (options && options->fake_tls_handshake) { DCHECK(!options->use_tls); net_socket = std::make_unique<jingle_glue::FakeSSLClientSocket>(
diff --git a/services/network/proxy_resolving_socket_factory_mojo.h b/services/network/proxy_resolving_socket_factory_mojo.h index b32c0824..f7c8d5b 100644 --- a/services/network/proxy_resolving_socket_factory_mojo.h +++ b/services/network/proxy_resolving_socket_factory_mojo.h
@@ -19,6 +19,7 @@ #include "services/network/tls_socket_factory.h" namespace net { +class NetworkIsolationKey; class URLRequestContext; } // namespace net @@ -33,6 +34,7 @@ // mojom::ProxyResolvingSocketFactory implementation. void CreateProxyResolvingSocket( const GURL& url, + const net::NetworkIsolationKey& network_isolation_key, mojom::ProxyResolvingSocketOptionsPtr options, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, mojo::PendingReceiver<mojom::ProxyResolvingSocket> receiver,
diff --git a/services/network/proxy_resolving_socket_mojo_unittest.cc b/services/network/proxy_resolving_socket_mojo_unittest.cc index 1a2b199..f840843a 100644 --- a/services/network/proxy_resolving_socket_mojo_unittest.cc +++ b/services/network/proxy_resolving_socket_mojo_unittest.cc
@@ -18,6 +18,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/data_pipe_utils.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" #include "net/proxy_resolution/configured_proxy_resolution_service.h" @@ -122,7 +123,7 @@ options->use_tls = use_tls_; options->fake_tls_handshake = fake_tls_handshake_; factory_remote_->CreateProxyResolvingSocket( - url, std::move(options), + url, net::NetworkIsolationKey(), std::move(options), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), std::move(receiver), std::move(socket_observer), base::BindLambdaForTesting( @@ -401,7 +402,7 @@ base::RunLoop run_loop; int net_error = net::OK; factory()->CreateProxyResolvingSocket( - kDestination, nullptr, + kDestination, net::NetworkIsolationKey(), nullptr, net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), socket.InitWithNewPipeAndPassReceiver(), mojo::NullRemote() /* observer */,
diff --git a/services/network/public/mojom/proxy_resolving_socket.mojom b/services/network/public/mojom/proxy_resolving_socket.mojom index 2fb1a98..3c5d790 100644 --- a/services/network/public/mojom/proxy_resolving_socket.mojom +++ b/services/network/public/mojom/proxy_resolving_socket.mojom
@@ -6,6 +6,7 @@ import "services/network/public/mojom/ip_endpoint.mojom"; import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom"; +import "services/network/public/mojom/network_isolation_key.mojom"; import "services/network/public/mojom/network_param.mojom"; import "services/network/public/mojom/ssl_config.mojom"; import "services/network/public/mojom/tcp_socket.mojom"; @@ -52,19 +53,25 @@ // factory instance. interface ProxyResolvingSocketFactory { // Creates a socket connected to |url|. This connection might be done through - // proxies if any is set in system's proxy settings. On success, |result| is - // net::OK. Caller is to use |send_stream| to send data and - // |receive_stream| to receive data over the connection. On failure, |result| - // is a network error code. |local_addr| contains the local address of the - // socket. |peer_addr| contains the peer address. If socket is connected to a - // proxy, |peer_addr| will be null. + // proxies if any is set in system's proxy settings. + // + // |network_isolation_key| indicates the network storage shard to use for + // shared resources, such as the DNS cache and shared proxy connections. + // + // On success, |result| is net::OK. Caller is to use |send_stream| to send + // data and |receive_stream| to receive data over the connection. On failure, + // |result| is a network error code. |local_addr| contains the local address + // of the socket. |peer_addr| contains the peer address. If socket is + // connected to a proxy, |peer_addr| will be null. // // If socket is closed before the callback can be completed, the callback will // be invoked with net::ERR_ABORTED. // // Any sockets that are created but are yet to be destroyed will be destroyed // when the implementation of this factory goes away. - CreateProxyResolvingSocket(url.mojom.Url url, + CreateProxyResolvingSocket( + url.mojom.Url url, + NetworkIsolationKey network_isolation_key, ProxyResolvingSocketOptions? options, MutableNetworkTrafficAnnotationTag traffic_annotation, pending_receiver<ProxyResolvingSocket> socket,
diff --git a/services/network/tls_client_socket_unittest.cc b/services/network/tls_client_socket_unittest.cc index f5aa04d..4c13918 100644 --- a/services/network/tls_client_socket_unittest.cc +++ b/services/network/tls_client_socket_unittest.cc
@@ -19,6 +19,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "net/base/completion_once_callback.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/base/test_completion_callback.h" #include "net/proxy_resolution/configured_proxy_resolution_service.h" #include "net/socket/server_socket.h" @@ -175,7 +176,7 @@ base::RunLoop run_loop; int net_error = net::ERR_FAILED; proxy_resolving_factory_->CreateProxyResolvingSocket( - url, nullptr /* options */, + url, net::NetworkIsolationKey(), nullptr /* options */, net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS), std::move(receiver), mojo::NullRemote() /* observer */, base::BindLambdaForTesting(
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 586f9b49..5c83c83 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -5111,43 +5111,6 @@ }, { "args": [ - "--platform=android", - "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" - ], - "isolate_name": "content_shell_crash_test", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "content_shell_crash_test", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "os": "Ubuntu-16.04", - "pool": "chromium.tests.avd.template", - "ssd": "1" - } - ], - "named_caches": [ - { - "name": "avd_generic_android23", - "path": ".android" - }, - { - "name": "system_images_android_23_google_apis_x86", - "path": ".emulator_sdk" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://content/shell:content_shell_crash_test/" - }, - { - "args": [ "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" ], "isolate_name": "monochrome_apk_checker", @@ -5181,83 +5144,6 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://chrome/android/monochrome:monochrome_apk_checker/" - }, - { - "args": [ - "BrowserMinidumpTest", - "--browser=android-chromium", - "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" - ], - "isolate_name": "telemetry_perf_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_chromium_minidump_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "os": "Ubuntu-16.04", - "pool": "chromium.tests.avd.template", - "ssd": "1" - } - ], - "named_caches": [ - { - "name": "avd_generic_android23", - "path": ".android" - }, - { - "name": "system_images_android_23_google_apis_x86", - "path": ".emulator_sdk" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/" - }, - { - "args": [ - "--extra-browser-args=--enable-crashpad", - "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" - ], - "isolate_name": "telemetry_perf_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_perf_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "os": "Ubuntu-16.04", - "pool": "chromium.tests.avd.template", - "ssd": "1" - } - ], - "idempotent": false, - "named_caches": [ - { - "name": "avd_generic_android23", - "path": ".android" - }, - { - "name": "system_images_android_23_google_apis_x86", - "path": ".emulator_sdk" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/" } ] },
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index bdc2dc3..4bb8021 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -33623,7 +33623,7 @@ "--avd-config=../../tools/android/avd/proto/generic_android28.textpb", "--git-revision=${got_revision}", "--avd-config=../../tools/android/avd/proto/generic_playstore_android28.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_m.chrome_public_test_apk.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter" ], "merge": { "args": [
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index c2d247a..26deb0f3 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -1,6 +1,41 @@ { "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, "AAAAA2 See generate_buildbot_json.py to make changes": {}, + "Linux ChromiumOS Full": { + "additional_compile_targets": [ + "app_list_unittests", + "base_unittests", + "browser_tests", + "cacheinvalidation_unittests", + "chromeos_unittests", + "components_unittests", + "compositor_unittests", + "content_browsertests", + "content_unittests", + "crypto_unittests", + "dbus_unittests", + "device_unittests", + "gcm_unit_tests", + "google_apis_unittests", + "gpu_unittests", + "interactive_ui_tests", + "ipc_tests", + "jingle_unittests", + "media_unittests", + "message_center_unittests", + "nacl_loader_unittests", + "net_unittests", + "ppapi_unittests", + "printing_unittests", + "remoting_unittests", + "sandbox_linux_unittests", + "sql_unittests", + "ui_base_unittests", + "unit_tests", + "url_unittests", + "views_unittests" + ] + }, "chromeos-amd64-generic-asan-rel": { "additional_compile_targets": [ "chromiumos_preflight"
diff --git a/testing/buildbot/chromium.ci.json b/testing/buildbot/chromium.ci.json index aa18c5a..8d2c527 100644 --- a/testing/buildbot/chromium.ci.json +++ b/testing/buildbot/chromium.ci.json
@@ -33670,6 +33670,41 @@ } ] }, + "Linux ChromiumOS Full": { + "additional_compile_targets": [ + "app_list_unittests", + "base_unittests", + "browser_tests", + "cacheinvalidation_unittests", + "chromeos_unittests", + "components_unittests", + "compositor_unittests", + "content_browsertests", + "content_unittests", + "crypto_unittests", + "dbus_unittests", + "device_unittests", + "gcm_unit_tests", + "google_apis_unittests", + "gpu_unittests", + "interactive_ui_tests", + "ipc_tests", + "jingle_unittests", + "media_unittests", + "message_center_unittests", + "nacl_loader_unittests", + "net_unittests", + "ppapi_unittests", + "printing_unittests", + "remoting_unittests", + "sandbox_linux_unittests", + "sql_unittests", + "ui_base_unittests", + "unit_tests", + "url_unittests", + "views_unittests" + ] + }, "Linux ChromiumOS MSan Tests": { "gtest_tests": [ { @@ -181378,43 +181413,6 @@ }, { "args": [ - "--platform=android", - "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" - ], - "isolate_name": "content_shell_crash_test", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "content_shell_crash_test", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "os": "Ubuntu-16.04", - "pool": "chromium.tests.avd.template", - "ssd": "1" - } - ], - "named_caches": [ - { - "name": "avd_generic_android23", - "path": ".android" - }, - { - "name": "system_images_android_23_google_apis_x86", - "path": ".emulator_sdk" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://content/shell:content_shell_crash_test/" - }, - { - "args": [ "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" ], "isolate_name": "monochrome_apk_checker", @@ -181448,83 +181446,6 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test_id_prefix": "ninja://chrome/android/monochrome:monochrome_apk_checker/" - }, - { - "args": [ - "BrowserMinidumpTest", - "--browser=android-chromium", - "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" - ], - "isolate_name": "telemetry_perf_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_chromium_minidump_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "os": "Ubuntu-16.04", - "pool": "chromium.tests.avd.template", - "ssd": "1" - } - ], - "named_caches": [ - { - "name": "avd_generic_android23", - "path": ".android" - }, - { - "name": "system_images_android_23_google_apis_x86", - "path": ".emulator_sdk" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/" - }, - { - "args": [ - "--extra-browser-args=--enable-crashpad", - "--avd-config=../../tools/android/avd/proto/generic_android23.textpb" - ], - "isolate_name": "telemetry_perf_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "telemetry_perf_unittests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "device_os": null, - "device_type": null, - "os": "Ubuntu-16.04", - "pool": "chromium.tests.avd.template", - "ssd": "1" - } - ], - "idempotent": false, - "named_caches": [ - { - "name": "avd_generic_android23", - "path": ".android" - }, - { - "name": "system_images_android_23_google_apis_x86", - "path": ".emulator_sdk" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 - }, - "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests/" } ] }, @@ -187004,7 +186925,7 @@ "--avd-config=../../tools/android/avd/proto/generic_android28.textpb", "--git-revision=${got_revision}", "--avd-config=../../tools/android/avd/proto/generic_playstore_android28.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_m.chrome_public_test_apk.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter" ], "merge": { "args": [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 35e72501d..29b714b 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -671,7 +671,7 @@ 'args': [ '--avd-config=../../tools/android/avd/proto/generic_playstore_android28.textpb', # https://crbug.com/1046059 - '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_m.chrome_public_test_apk.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter', ], 'swarming': { 'named_caches': [ @@ -897,6 +897,9 @@ }, }, 'content_shell_crash_test': { + 'remove_from': [ + 'android-marshmallow-x86-fyi-rel', # crbug.com/1084353 + ], 'modifications': { 'Win10 Tests x64 (dbg)': { 'experiment_percentage': 100, # https://crbug.com/861730 @@ -2089,6 +2092,11 @@ 'Linux Release (NVIDIA)', ], }, + 'telemetry_chromium_minidump_unittests': { + 'remove_from': [ + 'android-marshmallow-x86-fyi-rel', # crbug.com/1084352 + ], + }, 'telemetry_monochrome_minidump_unittests': { 'remove_from': [ # Monochrome isn't supported on M. @@ -2149,6 +2157,7 @@ }, }, 'remove_from': [ + 'android-marshmallow-x86-fyi-rel', # crbug.com/1084352 # There's no need to run telemetry_perf_unittests on both lollipop and # marshmallow on the CQ. https://crbug.com/1026487. 'android-marshmallow-arm64-rel',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index a7ca430..689ed46 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -812,6 +812,41 @@ 'name': 'chromium.chromiumos', 'mixins': ['chromium-tester-service-account'], 'machines': { + 'Linux ChromiumOS Full': { + 'additional_compile_targets': [ + 'app_list_unittests', + 'base_unittests', + 'browser_tests', + 'cacheinvalidation_unittests', + 'chromeos_unittests', + 'components_unittests', + 'compositor_unittests', + 'content_browsertests', + 'content_unittests', + 'crypto_unittests', + 'dbus_unittests', + 'device_unittests', + 'gcm_unit_tests', + 'google_apis_unittests', + 'gpu_unittests', + 'interactive_ui_tests', + 'ipc_tests', + 'jingle_unittests', + 'media_unittests', + 'message_center_unittests', + 'nacl_loader_unittests', + 'net_unittests', + 'ppapi_unittests', + 'printing_unittests', + 'remoting_unittests', + 'sandbox_linux_unittests', + 'sql_unittests', + 'ui_base_unittests', + 'unit_tests', + 'url_unittests', + 'views_unittests', + ], + }, 'chromeos-amd64-generic-asan-rel': { 'additional_compile_targets': [ 'chromiumos_preflight',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 2473d6e..b8be7af3 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1203,6 +1203,27 @@ ] } ], + "CSSReducedFontLoadingInvalidations": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CSSReducedFontLoadingInvalidations" + ] + } + ] + } + ], "CacheStorageEagerReading": [ { "platforms": [ @@ -2392,6 +2413,26 @@ ] } ], + "FindInPageBestEffortPriority": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20200601", + "enable_features": [ + "BlinkSchedulerBestEffortPriorityForFindInPage" + ] + } + ] + } + ], "FlexNG": [ { "platforms": [
diff --git a/third_party/blink/common/feature_policy/feature_policy.cc b/third_party/blink/common/feature_policy/feature_policy.cc index b34f95be..62e0fcbf 100644 --- a/third_party/blink/common/feature_policy/feature_policy.cc +++ b/third_party/blink/common/feature_policy/feature_policy.cc
@@ -453,10 +453,6 @@ FeatureDefault(FeaturePolicy::FeatureDefault::EnableForSelf)}, {mojom::FeaturePolicyFeature::kIdleDetection, FeatureDefault(FeaturePolicy::FeatureDefault::EnableForSelf)}, - {mojom::FeaturePolicyFeature::kLazyLoad, - FeatureDefault(FeaturePolicy::FeatureDefault::EnableForAll)}, - {mojom::FeaturePolicyFeature::kLoadingFrameDefaultEager, - FeatureDefault(FeaturePolicy::FeatureDefault::EnableForAll)}, {mojom::FeaturePolicyFeature::kMagnetometer, FeatureDefault(FeaturePolicy::FeatureDefault::EnableForSelf)}, {mojom::FeaturePolicyFeature::kMicrophone,
diff --git a/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom b/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom index adbeb99..ad49acbc 100644 --- a/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom +++ b/third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom
@@ -59,9 +59,6 @@ // which interfere with document's input stream (document.write(), // document.close(), etc.). kDocumentWrite = 28, - // TODO(ekaramad): kLazyLoad is deprecated; remove. - // Used to enforce lazyloading for a frame and any nested <iframe> or image. - kLazyLoad = 29, // Controls access to Screen Wake Lock kScreenWakeLock = 31, // These are the defined sandbox features implemented as policy-controlled @@ -85,9 +82,6 @@ // Controls access to Idle Detection kIdleDetection = 44, - // Loading policies. - kLoadingFrameDefaultEager = 48, - // Implements sandbox flag: allow-downloads. kDownloads = 49,
diff --git a/third_party/blink/public/mojom/use_counter/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/css_property_id.mojom index 8ce2c0e..77812cd 100644 --- a/third_party/blink/public/mojom/use_counter/css_property_id.mojom +++ b/third_party/blink/public/mojom/use_counter/css_property_id.mojom
@@ -708,6 +708,7 @@ kContentVisibility = 662, kTextDecorationThickness = 663, kPageOrientation = 664, + kAnimationTimeline = 665, // 1. Add new features above this line (don't change the assigned numbers of // the existing items). // 2. Run the src/tools/metrics/histograms/update_use_counter_css.py script
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 4bd4c4a..6b41478 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -242,8 +242,9 @@ BLINK_PLATFORM_EXPORT static void EnableTrustTokensAlwaysAllowIssuance(bool); BLINK_PLATFORM_EXPORT static void EnableInstalledApp(bool); - BLINK_PLATFORM_EXPORT static void EnableTransformInterop(bool); + BLINK_PLATFORM_EXPORT static void EnableVideoWakeLockOptimisationHiddenMuted( + bool); private: WebRuntimeFeatures();
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_data.cc b/third_party/blink/renderer/core/animation/css/css_animation_data.cc index 43fdebda..cb79e445 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation_data.cc +++ b/third_party/blink/renderer/core/animation/css/css_animation_data.cc
@@ -10,6 +10,7 @@ CSSAnimationData::CSSAnimationData() { name_list_.push_back(InitialName()); + timeline_list_.push_back(InitialTimeline()); iteration_count_list_.push_back(InitialIterationCount()); direction_list_.push_back(InitialDirection()); fill_mode_list_.push_back(InitialFillMode()); @@ -23,9 +24,15 @@ return name; } +const StyleNameOrKeyword& CSSAnimationData::InitialTimeline() { + DEFINE_STATIC_LOCAL(const StyleNameOrKeyword, name, (CSSValueID::kAuto)); + return name; +} + bool CSSAnimationData::AnimationsMatchForStyleRecalc( const CSSAnimationData& other) const { return name_list_ == other.name_list_ && + timeline_list_ == other.timeline_list_ && play_state_list_ == other.play_state_list_ && iteration_count_list_ == other.iteration_count_list_ && direction_list_ == other.direction_list_ &&
diff --git a/third_party/blink/renderer/core/animation/css/css_animation_data.h b/third_party/blink/renderer/core/animation/css/css_animation_data.h index 6466df5b..eb90165 100644 --- a/third_party/blink/renderer/core/animation/css/css_animation_data.h +++ b/third_party/blink/renderer/core/animation/css/css_animation_data.h
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/core/animation/css/css_timing_data.h" #include "third_party/blink/renderer/core/animation/timing.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" +#include "third_party/blink/renderer/core/style/style_name_or_keyword.h" namespace blink { @@ -31,6 +32,10 @@ Timing ConvertToTiming(size_t index) const; const Vector<AtomicString>& NameList() const { return name_list_; } + const Vector<StyleNameOrKeyword>& TimelineList() const { + return timeline_list_; + } + const Vector<double>& IterationCountList() const { return iteration_count_list_; } @@ -45,12 +50,14 @@ } Vector<AtomicString>& NameList() { return name_list_; } + Vector<StyleNameOrKeyword>& TimelineList() { return timeline_list_; } Vector<double>& IterationCountList() { return iteration_count_list_; } Vector<Timing::PlaybackDirection>& DirectionList() { return direction_list_; } Vector<Timing::FillMode>& FillModeList() { return fill_mode_list_; } Vector<EAnimPlayState>& PlayStateList() { return play_state_list_; } static const AtomicString& InitialName(); + static const StyleNameOrKeyword& InitialTimeline(); static Timing::PlaybackDirection InitialDirection() { return Timing::PlaybackDirection::NORMAL; } @@ -60,6 +67,7 @@ private: Vector<AtomicString> name_list_; + Vector<StyleNameOrKeyword> timeline_list_; Vector<double> iteration_count_list_; Vector<Timing::PlaybackDirection> direction_list_; Vector<Timing::FillMode> fill_mode_list_;
diff --git a/third_party/blink/renderer/core/animation/css/css_animations.cc b/third_party/blink/renderer/core/animation/css/css_animations.cc index 8b5ccaa..96d5b46 100644 --- a/third_party/blink/renderer/core/animation/css/css_animations.cc +++ b/third_party/blink/renderer/core/animation/css/css_animations.cc
@@ -1628,6 +1628,7 @@ case CSSPropertyID::kAnimationIterationCount: case CSSPropertyID::kAnimationName: case CSSPropertyID::kAnimationPlayState: + case CSSPropertyID::kAnimationTimeline: case CSSPropertyID::kAnimationTimingFunction: case CSSPropertyID::kContain: case CSSPropertyID::kDirection:
diff --git a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc index db52347..712fb3c8 100644 --- a/third_party/blink/renderer/core/css/css_computed_style_declaration.cc +++ b/third_party/blink/renderer/core/css/css_computed_style_declaration.cc
@@ -61,12 +61,12 @@ CSSPropertyID::kAnimationDelay, CSSPropertyID::kAnimationDirection, CSSPropertyID::kAnimationDuration, CSSPropertyID::kAnimationFillMode, CSSPropertyID::kAnimationIterationCount, CSSPropertyID::kAnimationName, - CSSPropertyID::kAnimationPlayState, CSSPropertyID::kAnimationTimingFunction, - CSSPropertyID::kAppearance, CSSPropertyID::kBackdropFilter, - CSSPropertyID::kBackfaceVisibility, CSSPropertyID::kBackgroundAttachment, - CSSPropertyID::kBackgroundBlendMode, CSSPropertyID::kBackgroundClip, - CSSPropertyID::kBackgroundColor, CSSPropertyID::kBackgroundImage, - CSSPropertyID::kBackgroundOrigin, + CSSPropertyID::kAnimationPlayState, CSSPropertyID::kAnimationTimeline, + CSSPropertyID::kAnimationTimingFunction, CSSPropertyID::kAppearance, + CSSPropertyID::kBackdropFilter, CSSPropertyID::kBackfaceVisibility, + CSSPropertyID::kBackgroundAttachment, CSSPropertyID::kBackgroundBlendMode, + CSSPropertyID::kBackgroundClip, CSSPropertyID::kBackgroundColor, + CSSPropertyID::kBackgroundImage, CSSPropertyID::kBackgroundOrigin, // more-specific background-position-x/y are non-standard CSSPropertyID::kBackgroundPosition, CSSPropertyID::kBackgroundRepeat, CSSPropertyID::kBackgroundSize, CSSPropertyID::kBaselineShift,
diff --git a/third_party/blink/renderer/core/css/css_font_face_rule.h b/third_party/blink/renderer/core/css/css_font_face_rule.h index 7a856db..e1b0ec0 100644 --- a/third_party/blink/renderer/core/css/css_font_face_rule.h +++ b/third_party/blink/renderer/core/css/css_font_face_rule.h
@@ -49,7 +49,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kFontFaceRule; } + CSSRule::Type GetType() const override { return kFontFaceRule; } Member<StyleRuleFontFace> font_face_rule_; mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_; @@ -58,7 +58,7 @@ template <> struct DowncastTraits<CSSFontFaceRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kFontFaceRule; + return rule.GetType() == CSSRule::kFontFaceRule; } };
diff --git a/third_party/blink/renderer/core/css/css_import_rule.h b/third_party/blink/renderer/core/css/css_import_rule.h index e9ae7f93..3755ec0 100644 --- a/third_party/blink/renderer/core/css/css_import_rule.h +++ b/third_party/blink/renderer/core/css/css_import_rule.h
@@ -48,7 +48,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kImportRule; } + CSSRule::Type GetType() const override { return kImportRule; } Member<StyleRuleImport> import_rule_; mutable Member<MediaList> media_cssom_wrapper_; @@ -58,7 +58,7 @@ template <> struct DowncastTraits<CSSImportRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kImportRule; + return rule.GetType() == CSSRule::kImportRule; } };
diff --git a/third_party/blink/renderer/core/css/css_keyframe_rule.h b/third_party/blink/renderer/core/css/css_keyframe_rule.h index c183cf89..98aa8887 100644 --- a/third_party/blink/renderer/core/css/css_keyframe_rule.h +++ b/third_party/blink/renderer/core/css/css_keyframe_rule.h
@@ -55,7 +55,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kKeyframeRule; } + CSSRule::Type GetType() const override { return kKeyframeRule; } Member<StyleRuleKeyframe> keyframe_; mutable Member<KeyframeStyleRuleCSSStyleDeclaration> @@ -67,7 +67,7 @@ template <> struct DowncastTraits<CSSKeyframeRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kKeyframeRule; + return rule.GetType() == CSSRule::kKeyframeRule; } };
diff --git a/third_party/blink/renderer/core/css/css_keyframes_rule.h b/third_party/blink/renderer/core/css/css_keyframes_rule.h index 593f24e..e7a96141 100644 --- a/third_party/blink/renderer/core/css/css_keyframes_rule.h +++ b/third_party/blink/renderer/core/css/css_keyframes_rule.h
@@ -117,7 +117,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kKeyframesRule; } + CSSRule::Type GetType() const override { return kKeyframesRule; } Member<StyleRuleKeyframes> keyframes_rule_; mutable HeapVector<Member<CSSKeyframeRule>> child_rule_cssom_wrappers_; @@ -128,7 +128,7 @@ template <> struct DowncastTraits<CSSKeyframesRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kKeyframesRule; + return rule.GetType() == CSSRule::kKeyframesRule; } };
diff --git a/third_party/blink/renderer/core/css/css_media_rule.h b/third_party/blink/renderer/core/css/css_media_rule.h index fd0b858..ca7d228 100644 --- a/third_party/blink/renderer/core/css/css_media_rule.h +++ b/third_party/blink/renderer/core/css/css_media_rule.h
@@ -47,7 +47,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kMediaRule; } + CSSRule::Type GetType() const override { return kMediaRule; } scoped_refptr<MediaQuerySet> MediaQueries() const; @@ -57,7 +57,7 @@ template <> struct DowncastTraits<CSSMediaRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kMediaRule; + return rule.GetType() == CSSRule::kMediaRule; } };
diff --git a/third_party/blink/renderer/core/css/css_namespace_rule.h b/third_party/blink/renderer/core/css/css_namespace_rule.h index be8e6879..48fc083 100644 --- a/third_party/blink/renderer/core/css/css_namespace_rule.h +++ b/third_party/blink/renderer/core/css/css_namespace_rule.h
@@ -28,7 +28,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kNamespaceRule; } + CSSRule::Type GetType() const override { return kNamespaceRule; } Member<StyleRuleNamespace> namespace_rule_; }; @@ -36,7 +36,7 @@ template <> struct DowncastTraits<CSSNamespaceRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kNamespaceRule; + return rule.GetType() == CSSRule::kNamespaceRule; } };
diff --git a/third_party/blink/renderer/core/css/css_page_rule.h b/third_party/blink/renderer/core/css/css_page_rule.h index c28d5c1f..161078e3 100644 --- a/third_party/blink/renderer/core/css/css_page_rule.h +++ b/third_party/blink/renderer/core/css/css_page_rule.h
@@ -52,7 +52,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kPageRule; } + CSSRule::Type GetType() const override { return kPageRule; } Member<StyleRulePage> page_rule_; mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_; @@ -61,7 +61,7 @@ template <> struct DowncastTraits<CSSPageRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kPageRule; + return rule.GetType() == CSSRule::kPageRule; } };
diff --git a/third_party/blink/renderer/core/css/css_page_rule_test.cc b/third_party/blink/renderer/core/css/css_page_rule_test.cc index 98332f4..a9bcbd4 100644 --- a/third_party/blink/renderer/core/css/css_page_rule_test.cc +++ b/third_party/blink/renderer/core/css/css_page_rule_test.cc
@@ -20,7 +20,7 @@ if (sheet.CssRules()) { EXPECT_EQ(1u, sheet.CssRules()->length()); EXPECT_EQ(String(css_rule), sheet.CssRules()->item(0)->cssText()); - EXPECT_EQ(CSSRule::kPageRule, sheet.CssRules()->item(0)->type()); + EXPECT_EQ(CSSRule::kPageRule, sheet.CssRules()->item(0)->GetType()); auto* page_rule = To<CSSPageRule>(sheet.CssRules()->item(0)); EXPECT_EQ(":left", page_rule->selectorText()); }
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5 index a4ddb4c3..ed5c4c2 100644 --- a/third_party/blink/renderer/core/css/css_properties.json5 +++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -598,6 +598,20 @@ valid_for_marker: true, }, { + name: "animation-timeline", + property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"], + style_builder_template: "animation", + style_builder_template_args: { + attribute: "Timeline", + }, + priority: "Animation", + keywords: ["none", "auto"], + typedom_types: ["Keyword"], + separator: ",", + valid_for_marker: true, + runtime_flag: "CSSScrollTimeline", + }, + { name: "animation-timing-function", property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"], style_builder_template: "animation",
diff --git a/third_party/blink/renderer/core/css/css_property_rule.h b/third_party/blink/renderer/core/css/css_property_rule.h index 52396a4..6a0c0c3a 100644 --- a/third_party/blink/renderer/core/css/css_property_rule.h +++ b/third_party/blink/renderer/core/css/css_property_rule.h
@@ -31,7 +31,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kPropertyRule; } + CSSRule::Type GetType() const override { return kPropertyRule; } Member<StyleRuleProperty> property_rule_; }; @@ -39,7 +39,7 @@ template <> struct DowncastTraits<CSSPropertyRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kPropertyRule; + return rule.GetType() == CSSRule::kPropertyRule; } };
diff --git a/third_party/blink/renderer/core/css/css_rule.h b/third_party/blink/renderer/core/css/css_rule.h index bcc7627e..c586238 100644 --- a/third_party/blink/renderer/core/css/css_rule.h +++ b/third_party/blink/renderer/core/css/css_rule.h
@@ -42,9 +42,8 @@ public: ~CSSRule() override = default; - // The values must match the table in [1]. See also css_rule.idl. - // [1] https://wiki.csswg.org/spec/cssom-constants enum Type { + // Web-exposed values, see css_rule.idl: kStyleRule = 1, kCharsetRule = 2, kImportRule = 3, @@ -56,12 +55,23 @@ kNamespaceRule = 10, kSupportsRule = 12, kViewportRule = 15, - kPropertyRule = 18, - // Experimental features below. Such features must be greater than 1000: - // the 0-1000 range is reserved by the CSS Working Group. + // CSSOM constants are deprecated [1], and there will be no new + // web-exposed values. + // + // [1] https://wiki.csswg.org/spec/cssom-constants + + // Values for internal use, not web-exposed: + kPropertyRule = 16, }; - virtual Type type() const = 0; + virtual Type GetType() const = 0; + + // https://drafts.csswg.org/cssom/#dom-cssrule-type + int type() const { + Type type = GetType(); + return type > Type::kViewportRule ? 0 : static_cast<int>(type); + } + virtual String cssText() const = 0; virtual void Reattach(StyleRuleBase*) = 0;
diff --git a/third_party/blink/renderer/core/css/css_rule.idl b/third_party/blink/renderer/core/css/css_rule.idl index 24c7dc1..00c3aec 100644 --- a/third_party/blink/renderer/core/css/css_rule.idl +++ b/third_party/blink/renderer/core/css/css_rule.idl
@@ -45,8 +45,4 @@ // CSS Conditional Rules // https://drafts.csswg.org/css-conditional/#extentions-to-cssrule-interface const unsigned short SUPPORTS_RULE = 12; - - // CSS Properties and Values Level 1 - // https://drafts.css-houdini.org/css-properties-values-api/#extensions-to-css-rule-interface - [RuntimeEnabled=CSSVariables2AtProperty] const unsigned short PROPERTY_RULE = 18; };
diff --git a/third_party/blink/renderer/core/css/css_string_value.h b/third_party/blink/renderer/core/css/css_string_value.h index 2641f37..7c9d034 100644 --- a/third_party/blink/renderer/core/css/css_string_value.h +++ b/third_party/blink/renderer/core/css/css_string_value.h
@@ -11,7 +11,7 @@ namespace blink { -class CSSStringValue : public CSSValue { +class CORE_EXPORT CSSStringValue : public CSSValue { public: CSSStringValue(const String&);
diff --git a/third_party/blink/renderer/core/css/css_style_declaration_test.cc b/third_party/blink/renderer/core/css/css_style_declaration_test.cc index 5bfe780..9d01697e 100644 --- a/third_party/blink/renderer/core/css/css_style_declaration_test.cc +++ b/third_party/blink/renderer/core/css/css_style_declaration_test.cc
@@ -20,7 +20,7 @@ sheet.AddCSSRules("div { padding: var(--p); }"); ASSERT_TRUE(sheet.CssRules()); ASSERT_EQ(1u, sheet.CssRules()->length()); - ASSERT_EQ(CSSRule::kStyleRule, sheet.CssRules()->item(0)->type()); + ASSERT_EQ(CSSRule::kStyleRule, sheet.CssRules()->item(0)->GetType()); CSSStyleRule* style_rule = To<CSSStyleRule>(sheet.CssRules()->item(0)); CSSStyleDeclaration* style = style_rule->style(); ASSERT_TRUE(style);
diff --git a/third_party/blink/renderer/core/css/css_style_rule.h b/third_party/blink/renderer/core/css/css_style_rule.h index 6a034c2..3b0233f9 100644 --- a/third_party/blink/renderer/core/css/css_style_rule.h +++ b/third_party/blink/renderer/core/css/css_style_rule.h
@@ -57,7 +57,7 @@ void Trace(Visitor*) const override; private: - CSSRule::Type type() const override { return kStyleRule; } + CSSRule::Type GetType() const override { return kStyleRule; } Member<StyleRule> style_rule_; mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_; @@ -67,7 +67,7 @@ template <> struct DowncastTraits<CSSStyleRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kStyleRule; + return rule.GetType() == CSSRule::kStyleRule; } };
diff --git a/third_party/blink/renderer/core/css/css_supports_rule.h b/third_party/blink/renderer/core/css/css_supports_rule.h index a946911c..a15d68b3 100644 --- a/third_party/blink/renderer/core/css/css_supports_rule.h +++ b/third_party/blink/renderer/core/css/css_supports_rule.h
@@ -46,13 +46,13 @@ String cssText() const override; private: - CSSRule::Type type() const override { return kSupportsRule; } + CSSRule::Type GetType() const override { return kSupportsRule; } }; template <> struct DowncastTraits<CSSSupportsRule> { static bool AllowFrom(const CSSRule& rule) { - return rule.type() == CSSRule::kSupportsRule; + return rule.GetType() == CSSRule::kSupportsRule; } };
diff --git a/third_party/blink/renderer/core/css/parser/css.proto b/third_party/blink/renderer/core/css/parser/css.proto index 973f7c8..652eb73 100644 --- a/third_party/blink/renderer/core/css/parser/css.proto +++ b/third_party/blink/renderer/core/css/parser/css.proto
@@ -1441,7 +1441,8 @@ OVERSCROLL_BEHAVIOR_BLOCK = 552; OVERSCROLL_BEHAVIOR_X = 553; OVERSCROLL_BEHAVIOR_Y = 554; - INVALID_PROPERTY = 555; + ANIMATION_TIMELINE = 555; + INVALID_PROPERTY = 556; } required NameId name_id = 1; }
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index 1346dd54..4c57e3cc 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -2712,6 +2712,19 @@ return ZoomAdjustedPixelValueForLength(gap_length.GetLength(), style); } +CSSValue* ComputedStyleUtils::ValueForStyleName(const StyleName& name) { + if (name.IsCustomIdent()) + return MakeGarbageCollected<CSSCustomIdentValue>(name.GetValue()); + return MakeGarbageCollected<CSSStringValue>(name.GetValue()); +} + +CSSValue* ComputedStyleUtils::ValueForStyleNameOrKeyword( + const StyleNameOrKeyword& value) { + if (value.IsKeyword()) + return CSSIdentifierValue::Create(value.GetKeyword()); + return ValueForStyleName(value.GetName()); +} + std::unique_ptr<CrossThreadStyleValue> ComputedStyleUtils::CrossThreadStyleValueFromCSSStyleValue( CSSStyleValue* style_value) {
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.h b/third_party/blink/renderer/core/css/properties/computed_style_utils.h index 790aaf3..3acd1dd 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.h +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.h
@@ -239,6 +239,9 @@ static CSSValue* ScrollCustomizationFlagsToCSSValue( scroll_customization::ScrollDirection); static CSSValue* ValueForGapLength(const GapLength&, const ComputedStyle&); + static CSSValue* ValueForStyleName(const StyleName&); + static CSSValue* ValueForStyleNameOrKeyword(const StyleNameOrKeyword&); + static std::unique_ptr<CrossThreadStyleValue> CrossThreadStyleValueFromCSSStyleValue(CSSStyleValue* style_value);
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc index ff1582a6..35490862 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils_test.cc
@@ -4,6 +4,11 @@ #include "third_party/blink/renderer/core/css/properties/computed_style_utils.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/css/css_custom_ident_value.h" +#include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_string_value.h" +#include "third_party/blink/renderer/core/style/style_name.h" +#include "third_party/blink/renderer/core/style/style_name_or_keyword.h" #include "third_party/googletest/src/googletest/include/gtest/gtest.h" namespace blink { @@ -41,4 +46,25 @@ "matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)"); } +TEST(ComputedStyleUtilsTest, ValueForStyleName) { + EXPECT_EQ(*ComputedStyleUtils::ValueForStyleName( + StyleName("foo", StyleName::Type::kCustomIdent)), + *MakeGarbageCollected<CSSCustomIdentValue>("foo")); + EXPECT_EQ(*ComputedStyleUtils::ValueForStyleName( + StyleName("foo", StyleName::Type::kString)), + *MakeGarbageCollected<CSSStringValue>("foo")); +} + +TEST(ComputedStyleUtilsTest, ValueForStyleNameOrKeyword) { + EXPECT_EQ(*ComputedStyleUtils::ValueForStyleNameOrKeyword(StyleNameOrKeyword( + StyleName("foo", StyleName::Type::kCustomIdent))), + *MakeGarbageCollected<CSSCustomIdentValue>("foo")); + EXPECT_EQ(*ComputedStyleUtils::ValueForStyleNameOrKeyword( + StyleNameOrKeyword(StyleName("foo", StyleName::Type::kString))), + *MakeGarbageCollected<CSSStringValue>("foo")); + EXPECT_EQ(*ComputedStyleUtils::ValueForStyleNameOrKeyword( + StyleNameOrKeyword(CSSValueID::kNone)), + *MakeGarbageCollected<CSSIdentifierValue>(CSSValueID::kNone)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc index 7e66f00..5f5a0f1 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/css_ray_value.h" #include "third_party/blink/renderer/core/css/css_shadow_value.h" +#include "third_party/blink/renderer/core/css/css_string_value.h" #include "third_party/blink/renderer/core/css/css_timing_function_value.h" #include "third_party/blink/renderer/core/css/css_uri_value.h" #include "third_party/blink/renderer/core/css/css_value.h" @@ -568,6 +569,20 @@ return css_property_parser_helpers::ConsumeCustomIdent(range, context); } +CSSValue* ConsumeAnimationTimeline(CSSParserTokenRange& range, + const CSSParserContext& context) { + if (auto* value = + css_property_parser_helpers::ConsumeIdent<CSSValueID::kNone, + CSSValueID::kAuto>(range)) { + return value; + } + if (auto* value = + css_property_parser_helpers::ConsumeCustomIdent(range, context)) { + return value; + } + return css_property_parser_helpers::ConsumeString(range); +} + CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange& range, const CSSParserContext& context) { CSSValueID id = range.Peek().Id();
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h index 6cf2745..ce0c483 100644 --- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h +++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -66,6 +66,8 @@ CSSValue* ConsumeAnimationName(CSSParserTokenRange&, const CSSParserContext&, bool allow_quoted_name); +CSSValue* ConsumeAnimationTimeline(CSSParserTokenRange&, + const CSSParserContext&); CSSValue* ConsumeAnimationTimingFunction(CSSParserTokenRange&, const CSSParserContext&); bool ConsumeAnimationShorthand(
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index aadd23d..9e06f679 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -348,6 +348,34 @@ return value; } +const CSSValue* AnimationTimeline::ParseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext& context, + const CSSParserLocalContext& local_context) const { + return css_property_parser_helpers::ConsumeCommaSeparatedList( + css_parsing_utils::ConsumeAnimationTimeline, range, context); +} + +const CSSValue* AnimationTimeline::CSSValueFromComputedStyleInternal( + const ComputedStyle& style, + const SVGComputedStyle&, + const LayoutObject*, + bool allow_visited_style) const { + CSSValueList* list = CSSValueList::CreateCommaSeparated(); + const CSSAnimationData* animation_data = style.Animations(); + if (animation_data) { + for (const auto& timeline : animation_data->TimelineList()) + list->Append(*ComputedStyleUtils::ValueForStyleNameOrKeyword(timeline)); + } else { + list->Append(*InitialValue()); + } + return list; +} + +const CSSValue* AnimationTimeline::InitialValue() const { + return CSSIdentifierValue::Create(CSSValueID::kAuto); +} + const CSSValue* AnimationTimingFunction::ParseSingleValue( CSSParserTokenRange& range, const CSSParserContext& context,
diff --git a/third_party/blink/renderer/core/css/resolver/css_property_priority.h b/third_party/blink/renderer/core/css/resolver/css_property_priority.h index 1e965ec..04f8f7ac 100644 --- a/third_party/blink/renderer/core/css/resolver/css_property_priority.h +++ b/third_party/blink/renderer/core/css/resolver/css_property_priority.h
@@ -64,7 +64,7 @@ CSSPropertyPriorityData<kAnimationPropertyPriority>::Last() { static_assert( static_cast<int>(CSSPropertyID::kTransitionTimingFunction) == - static_cast<int>(CSSPropertyID::kAnimationDelay) + 11, + static_cast<int>(CSSPropertyID::kAnimationDelay) + 12, "CSSPropertyID::kTransitionTimingFunction should be the end of the high " "priority property range"); static_assert(
diff --git a/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc b/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc index 46c9f870..8c8645b 100644 --- a/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc +++ b/third_party/blink/renderer/core/css/resolver/css_to_style_map.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/animation/css/css_animation_data.h" #include "third_party/blink/renderer/core/css/css_border_image_slice_value.h" #include "third_party/blink/renderer/core/css/css_custom_ident_value.h" +#include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h" #include "third_party/blink/renderer/core/css/css_quad_value.h" @@ -386,6 +387,23 @@ return CSSAnimationData::InitialName(); } +StyleNameOrKeyword CSSToStyleMap::MapAnimationTimeline(const CSSValue& value) { + if (value.IsInitialValue()) + return CSSAnimationData::InitialTimeline(); + if (auto* ident = DynamicTo<CSSIdentifierValue>(value)) { + DCHECK(ident->GetValueID() == CSSValueID::kAuto || + ident->GetValueID() == CSSValueID::kNone); + return StyleNameOrKeyword(ident->GetValueID()); + } + if (auto* custom_ident = DynamicTo<CSSCustomIdentValue>(value)) { + return StyleNameOrKeyword( + StyleName(custom_ident->Value(), StyleName::Type::kCustomIdent)); + } + return StyleNameOrKeyword( + StyleName(AtomicString(To<CSSStringValue>(value).Value()), + StyleName::Type::kString)); +} + EAnimPlayState CSSToStyleMap::MapAnimationPlayState(const CSSValue& value) { if (value.IsInitialValue()) return CSSAnimationData::InitialPlayState();
diff --git a/third_party/blink/renderer/core/css/resolver/css_to_style_map.h b/third_party/blink/renderer/core/css/resolver/css_to_style_map.h index 9781979..3d7f101fe 100644 --- a/third_party/blink/renderer/core/css/resolver/css_to_style_map.h +++ b/third_party/blink/renderer/core/css/resolver/css_to_style_map.h
@@ -23,10 +23,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CSS_TO_STYLE_MAP_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RESOLVER_CSS_TO_STYLE_MAP_H_ +#include "third_party/blink/renderer/core/animation/css/css_animation_data.h" #include "third_party/blink/renderer/core/animation/css/css_transition_data.h" #include "third_party/blink/renderer/core/animation/timing.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/style/computed_style_constants.h" +#include "third_party/blink/renderer/core/style/style_name_or_keyword.h" #include "third_party/blink/renderer/platform/animation/timing_function.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -73,6 +75,7 @@ static Timing::FillMode MapAnimationFillMode(const CSSValue&); static double MapAnimationIterationCount(const CSSValue&); static AtomicString MapAnimationName(const CSSValue&); + static StyleNameOrKeyword MapAnimationTimeline(const CSSValue&); static EAnimPlayState MapAnimationPlayState(const CSSValue&); static CSSTransitionData::TransitionProperty MapAnimationProperty( const CSSValue&);
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 5656070..b61c1832 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -8444,12 +8444,6 @@ return false; } -bool Document::IsLazyLoadPolicyEnforced() const { - return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() && - !GetSecurityContext().GetFeaturePolicy()->IsFeatureEnabled( - mojom::blink::FeaturePolicyFeature::kLazyLoad); -} - bool Document::IsFocusAllowed() const { if (GetFrame() && GetFrame()->GetPage()->InsidePortal()) return false;
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 3dad7c2..a5cf630a 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -1561,7 +1561,6 @@ } bool IsVerticalScrollEnforced() const { return is_vertical_scroll_enforced_; } - bool IsLazyLoadPolicyEnforced() const; bool IsFocusAllowed() const; NavigationInitiatorImpl& NavigationInitiator();
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 b/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 index fae40c28..69f8ff5 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 +++ b/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5
@@ -189,16 +189,6 @@ depends_on: ["IdleDetection"], }, { - name: "LazyLoad", - feature_policy_name: "lazyload", - depends_on: ["ExperimentalProductivityFeatures"], - }, - { - name: "LoadingFrameDefaultEager", - feature_policy_name: "loading-frame-default-eager", - depends_on: ["ExperimentalProductivityFeatures"] - }, - { name: "Magnetometer", feature_policy_name: "magnetometer", },
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc index 9b434d73..1a5800b56 100644 --- a/third_party/blink/renderer/core/frame/frame_serializer.cc +++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -488,7 +488,7 @@ DCHECK(rule->parentStyleSheet()->OwnerDocument()); Document& document = *rule->parentStyleSheet()->OwnerDocument(); - switch (rule->type()) { + switch (rule->GetType()) { case CSSRule::kStyleRule: RetrieveResourcesForProperties( &To<CSSStyleRule>(rule)->GetStyleRule()->Properties(), document);
diff --git a/third_party/blink/renderer/core/frame/remote_frame.cc b/third_party/blink/renderer/core/frame/remote_frame.cc index e06f807..ca86c50 100644 --- a/third_party/blink/renderer/core/frame/remote_frame.cc +++ b/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -729,8 +729,17 @@ IsIgnoredForHitTest()); } } + HTMLFrameOwnerElement* owner = To<HTMLFrameOwnerElement>(Owner()); + owner->SetNeedsCompositingUpdate(); - To<HTMLFrameOwnerElement>(Owner())->SetNeedsCompositingUpdate(); + if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { + // New layers for remote frames are controlled by Blink's embedder. + // To ensure the new surface is painted, we need to repaint the frame + // owner's PaintLayer. + LayoutBoxModelObject* layout_object = owner->GetLayoutBoxModelObject(); + if (layout_object && layout_object->Layer()) + layout_object->Layer()->SetNeedsRepaint(); + } } void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type,
diff --git a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc index 02ff170f..fe8a7f6 100644 --- a/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc +++ b/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc
@@ -490,8 +490,7 @@ ((event.key() == "ArrowDown" && event.getModifierState("Alt")) || (LayoutTheme::GetTheme().ShouldOpenPickerWithF4Key() && event.key() == "F4") || - (features::IsFormControlsRefreshEnabled() && - (event.key() == "Enter" || event.key() == " ")))) { + (features::IsFormControlsRefreshEnabled() && event.key() == " "))) { if (PickerIndicatorElement* element = GetPickerIndicatorElement()) element->OpenPopup(); event.SetDefaultHandled();
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 788a946..beef3ca 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -474,13 +474,10 @@ // Update the |should_lazy_load_children_| value according to the "loading" // attribute immediately, so that it still gets respected even if the "src" // attribute gets parsed in ParseAttribute() before the "loading" attribute - // does. Note that when the *feature policy* for "lazyload" is disabled, the - // attribute value loading="eager" is ignored (i.e., interpreted as - // "auto" instead). + // does. if (should_lazy_load_children_ && EqualIgnoringASCIICase(FastGetAttribute(html_names::kLoadingAttr), - "eager") && - !GetDocument().IsLazyLoadPolicyEnforced()) { + "eager")) { should_lazy_load_children_ = false; } @@ -536,13 +533,8 @@ if (IsPlugin()) request.SetSkipServiceWorker(true); - // When the feature policy "loading-frame-default-eager" is disabled in - // the document, loading attribute value "auto" (or unset/invalid values) will - // also be interpreted as "lazy". const auto& loading_attr = FastGetAttribute(html_names::kLoadingAttr); - bool loading_lazy_set = EqualIgnoringASCIICase(loading_attr, "lazy") || - (IsLoadingFrameDefaultEagerEnforced() && - !EqualIgnoringASCIICase(loading_attr, "eager")); + bool loading_lazy_set = EqualIgnoringASCIICase(loading_attr, "lazy"); if (!lazy_load_frame_observer_ && IsFrameLazyLoadable(GetDocument(), url, loading_lazy_set, @@ -586,11 +578,7 @@ void HTMLFrameOwnerElement::ParseAttribute( const AttributeModificationParams& params) { if (params.name == html_names::kLoadingAttr) { - // Note that when the *feature policy* for "lazyload" is disabled, the - // attribute value loading="eager" is ignored (i.e., interpreted as - // "auto" instead). - if (EqualIgnoringASCIICase(params.new_value, "eager") && - !GetDocument().IsLazyLoadPolicyEnforced()) { + if (EqualIgnoringASCIICase(params.new_value, "eager")) { UseCounter::Count(GetDocument(), WebFeature::kLazyLoadFrameLoadingAttributeEager); should_lazy_load_children_ = false; @@ -636,10 +624,4 @@ FrameOwner::Trace(visitor); } -bool HTMLFrameOwnerElement::IsLoadingFrameDefaultEagerEnforced() const { - return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() && - !GetDocument().IsFeatureEnabled( - mojom::blink::FeaturePolicyFeature::kLoadingFrameDefaultEager); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.h b/third_party/blink/renderer/core/html/html_frame_owner_element.h index c541321f..23d019e 100644 --- a/third_party/blink/renderer/core/html/html_frame_owner_element.h +++ b/third_party/blink/renderer/core/html/html_frame_owner_element.h
@@ -203,8 +203,6 @@ return network::mojom::ReferrerPolicy::kDefault; } - bool IsLoadingFrameDefaultEagerEnforced() const; - Member<Frame> content_frame_; Member<EmbeddedContentView> embedded_content_view_; FramePolicy frame_policy_;
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc index 477811d..010b716 100644 --- a/third_party/blink/renderer/core/html/html_image_element.cc +++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -287,8 +287,7 @@ UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute); decoding_mode_ = ParseImageDecodingMode(params.new_value); } else if (name == html_names::kLoadingAttr && - EqualIgnoringASCIICase(params.new_value, "eager") && - !GetDocument().IsLazyLoadPolicyEnforced()) { + EqualIgnoringASCIICase(params.new_value, "eager")) { GetImageLoader().LoadDeferredImage(referrer_policy_); } else if (name == html_names::kImportanceAttr && RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) {
diff --git a/third_party/blink/renderer/core/html/html_template_element.cc b/third_party/blink/renderer/core/html/html_template_element.cc index d77718c3..13b4401 100644 --- a/third_party/blink/renderer/core/html/html_template_element.cc +++ b/third_party/blink/renderer/core/html/html_template_element.cc
@@ -46,7 +46,7 @@ HTMLTemplateElement::~HTMLTemplateElement() = default; DocumentFragment* HTMLTemplateElement::ContentInternal() const { - if (!content_) + if (!content_ && GetExecutionContext()) content_ = MakeGarbageCollected<TemplateContentDocumentFragment>( GetDocument().EnsureTemplateDocument(), const_cast<HTMLTemplateElement*>(this)); @@ -76,7 +76,7 @@ void HTMLTemplateElement::DidMoveToNewDocument(Document& old_document) { HTMLElement::DidMoveToNewDocument(old_document); - if (!content_) + if (!content_ || !GetExecutionContext()) return; GetDocument().EnsureTemplateDocument().AdoptIfNeeded(*content_); }
diff --git a/third_party/blink/renderer/core/html/media/video_wake_lock.cc b/third_party/blink/renderer/core/html/media/video_wake_lock.cc index 66841ff..c90cede 100644 --- a/third_party/blink/renderer/core/html/media/video_wake_lock.cc +++ b/third_party/blink/renderer/core/html/media/video_wake_lock.cc
@@ -30,7 +30,10 @@ this, true); VideoElement().addEventListener(event_type_names::kVolumechange, this, true); - StartIntersectionObserver(); + if (RuntimeEnabledFeatures::VideoWakeLockOptimisationHiddenMutedEnabled()) + StartIntersectionObserver(); + else + is_visible_ = true; RemotePlaybackController* remote_playback_controller = RemotePlaybackController::From(VideoElement()); @@ -43,8 +46,10 @@ void VideoWakeLock::ElementDidMoveToNewDocument() { SetExecutionContext(VideoElement().GetExecutionContext()); - intersection_observer_->disconnect(); - StartIntersectionObserver(); + if (RuntimeEnabledFeatures::VideoWakeLockOptimisationHiddenMutedEnabled()) { + intersection_observer_->disconnect(); + StartIntersectionObserver(); + } } void VideoWakeLock::PageVisibilityChanged() { @@ -53,6 +58,8 @@ void VideoWakeLock::OnVisibilityChanged( const HeapVector<Member<IntersectionObserverEntry>>& entries) { + DCHECK(RuntimeEnabledFeatures::VideoWakeLockOptimisationHiddenMutedEnabled()); + is_visible_ = (entries.back()->intersectionRatio() > 0); Update(); }
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index f80ec126..4a02071 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -295,13 +295,6 @@ request->SetCharset(Charset()); request->SetDefer(defer_); - LoadingAttrValue effective_loading_attr_value = loading_attr_value_; - // If the 'lazyload' feature policy is enforced, the attribute value - // loading='eager' is considered as 'auto'. - if (effective_loading_attr_value == LoadingAttrValue::kEager && - document_parameters.lazyload_policy_enforced) { - effective_loading_attr_value = LoadingAttrValue::kAuto; - } if (type == ResourceType::kImage && Match(tag_impl_, html_names::kImgTag) && IsLazyLoadImageDeferable(document_parameters)) { return nullptr; @@ -559,14 +552,7 @@ return false; } - // If the 'lazyload' feature policy is enforced, the attribute value - // loading='eager' is considered as 'auto'. - LoadingAttrValue effective_loading_attr_value = loading_attr_value_; - if (effective_loading_attr_value == LoadingAttrValue::kEager && - document_parameters.lazyload_policy_enforced) { - effective_loading_attr_value = LoadingAttrValue::kAuto; - } - switch (effective_loading_attr_value) { + switch (loading_attr_value_) { case LoadingAttrValue::kEager: return false; case LoadingAttrValue::kLazy: @@ -1114,7 +1100,6 @@ referrer_policy = document->GetReferrerPolicy(); integrity_features = SubresourceIntegrityHelper::GetFeatures(document->GetExecutionContext()); - lazyload_policy_enforced = document->IsLazyLoadPolicyEnforced(); if (document->Loader() && document->Loader()->GetFrame()) { lazy_load_image_setting = document->Loader()->GetFrame()->GetLazyLoadImageSetting();
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.h b/third_party/blink/renderer/core/html/parser/html_preload_scanner.h index 429b1495..7a25498 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.h +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.h
@@ -67,7 +67,6 @@ bool viewport_meta_enabled; network::mojom::ReferrerPolicy referrer_policy; SubresourceIntegrity::IntegrityFeatures integrity_features; - bool lazyload_policy_enforced; LocalFrame::LazyLoadImageSetting lazy_load_image_setting; WeakPersistent<LazyLoadImageObserver> lazy_load_image_observer; };
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index a19d93d..33fbe43 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -1225,7 +1225,6 @@ ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg'>", true}, @@ -1245,7 +1244,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureDisabledWithAttribute) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg' loading='auto'>", false}, @@ -1264,7 +1262,6 @@ ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg' loading='auto'>", true}, @@ -1282,7 +1279,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureExplicitEnabledWithAttribute) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg' loading='auto'>", false}, @@ -1302,7 +1298,6 @@ ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); PreloadScannerTestCase test_cases[] = { {"http://example.test", "<img src='foo.jpg' height='20px' width='20px'>", @@ -1340,7 +1335,6 @@ LazyLoadImage_FeatureExplicitPreloadForLargeImages) { // Large images should not be preloaded, when loading is lazy. ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); PreloadScannerTestCase test_cases[] = { {"http://example.test", @@ -1366,30 +1360,27 @@ Test(test_case); } +// TODO(domfarolino): Before merging, can we just delete this test, since we no +// longer have metadata fetching? TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisableMetadataFetch) { - GetDocument().GetSettings()->SetLazyLoadEnabled(true); struct TestCase { bool automatic_lazy_image_loading_enabled; const char* loading_attr_value; bool expected_is_preload; - // If preload happens, whether it is a fetch of placeholder or full image. - bool expected_is_placeholder_fetch; }; const TestCase test_cases[] = { - // The lazyload eligible cases should not trigger any preload when - // metadata fetch feature disabled, and trigger placeholder fetch if - // metadata fetch feature is active. - {false, "lazy", false, false}, - {true, "lazy", false, false}, - {true, "auto", false, false}, + // The lazyload eligible cases should not trigger a preload. + {false, "lazy", false}, + {true, "lazy", false}, + {true, "auto", false}, // Lazyload ineligible case. - {false, "auto", true, false}, + {false, "auto", true}, // Full image should be fetched when loading='eager' irrespective of - // automatic lazyload or metadata fetch feature states. - {false, "eager", true, false}, - {true, "eager", true, false}, + // automatic lazyload feature state. + {false, "eager", true}, + {true, "eager", true}, }; for (const auto& test_case : test_cases) { ScopedAutomaticLazyImageLoadingForTest @@ -1402,8 +1393,7 @@ const std::string img_html = base::StringPrintf( "<img src='foo.jpg' loading='%s'>", test_case.loading_attr_value); if (test_case.expected_is_preload) { - LazyLoadImageTestCase test_preload = { - img_html.c_str(), test_case.expected_is_placeholder_fetch}; + LazyLoadImageTestCase test_preload = {img_html.c_str(), false}; Test(test_preload); } else { PreloadScannerTestCase test_no_preload = { @@ -1421,7 +1411,6 @@ ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1); RunSetUp(kViewportEnabled); @@ -1438,7 +1427,6 @@ ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1); RunSetUp(kViewportEnabled); @@ -1456,7 +1444,6 @@ ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1); RunSetUp(kViewportEnabled);
diff --git a/third_party/blink/renderer/core/html/subresource_redirect_test.cc b/third_party/blink/renderer/core/html/subresource_redirect_test.cc index e7f15117..9a3422d 100644 --- a/third_party/blink/renderer/core/html/subresource_redirect_test.cc +++ b/third_party/blink/renderer/core/html/subresource_redirect_test.cc
@@ -66,9 +66,6 @@ // This test verifies subresource redirect previews state based on different // states of SaveData, LazyLoad, SubresourceRedirect features. TEST_P(SubresourceRedirectSimTest, CSSBackgroundImage) { - WebView().GetPage()->GetSettings().SetLazyLoadEnabled( - is_lazyload_image_enabled()); - SimRequest image_resource("https://example.com/img.png", "image/png"); LoadMainResource(String::Format(R"HTML( <style>
diff --git a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc index 5a4e9bb..1a052a4 100644 --- a/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_animation_agent.cc
@@ -447,7 +447,7 @@ css_agent_->FindEffectiveDeclaration(*property, styles); // Ignore inline styles. if (!style || !style->ParentStyleSheet() || !style->parentRule() || - style->parentRule()->type() != CSSRule::kStyleRule) + style->parentRule()->GetType() != CSSRule::kStyleRule) continue; digestor.UpdateUtf8(property->GetPropertyNameString()); digestor.UpdateUtf8(css_agent_->StyleSheetId(style->ParentStyleSheet()));
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 bc40f7c..ecfd654 100644 --- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -918,8 +918,8 @@ const CSSRuleVector& flat_rules = style_sheet->FlatRules(); for (unsigned i = 0; i < flat_rules.size(); ++i) { CSSRule* rule = flat_rules.at(i).Get(); - if (rule->type() == CSSRule::kMediaRule || - rule->type() == CSSRule::kImportRule) + if (rule->GetType() == CSSRule::kMediaRule || + rule->GetType() == CSSRule::kImportRule) CollectMediaQueriesFromRule(rule, medias->get()); } } @@ -2534,7 +2534,7 @@ HeapHashMap<Member<const StyleRule>, Member<CSSStyleRule>> rule_to_css_rule; const CSSRuleVector& css_rules = style_sheet->FlatRules(); for (auto css_rule : css_rules) { - if (css_rule->type() != CSSRule::kStyleRule) + if (css_rule->GetType() != CSSRule::kStyleRule) continue; CSSStyleRule* css_style_rule = AsCSSStyleRule(css_rule); rule_to_css_rule.Set(css_style_rule->GetStyleRule(), css_style_rule);
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc index 9bb369a..8f3ba7d 100644 --- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc +++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -534,7 +534,7 @@ // The result->append()'ed types should be exactly the same as in // flattenSourceData(). - switch (rule->type()) { + switch (rule->GetType()) { case CSSRule::kStyleRule: case CSSRule::kImportRule: case CSSRule::kCharsetRule: @@ -1026,7 +1026,7 @@ CSSRule* rule = RuleForSourceData(source_data); if (!rule || !rule->parentStyleSheet() || - rule->type() != CSSRule::kStyleRule) { + rule->GetType() != CSSRule::kStyleRule) { exception_state.ThrowDOMException( DOMExceptionCode::kNotFoundError, "Source range didn't match existing style source range"); @@ -1065,7 +1065,7 @@ CSSRule* rule = RuleForSourceData(source_data); if (!rule || !rule->parentStyleSheet() || - rule->type() != CSSRule::kKeyframeRule) { + rule->GetType() != CSSRule::kKeyframeRule) { exception_state.ThrowDOMException( DOMExceptionCode::kNotFoundError, "Source range didn't match existing style source range"); @@ -1145,7 +1145,7 @@ CSSRule* rule = RuleForSourceData(source_data); if (!rule || !rule->parentStyleSheet() || - rule->type() != CSSRule::kMediaRule) { + rule->GetType() != CSSRule::kMediaRule) { exception_state.ThrowDOMException( DOMExceptionCode::kNotFoundError, "Source range didn't match existing style source range"); @@ -1259,7 +1259,7 @@ exception_state); CSSRule* rule = RuleForSourceData(containing_rule_source_data); - if (!rule || rule->type() != CSSRule::kMediaRule) { + if (!rule || rule->GetType() != CSSRule::kMediaRule) { exception_state.ThrowDOMException(DOMExceptionCode::kNotFoundError, "Cannot insert rule in non-media rule."); return nullptr; @@ -1342,7 +1342,7 @@ } CSSRule* parent_rule = rule->parentRule(); if (parent_rule) { - if (parent_rule->type() != CSSRule::kMediaRule) { + if (parent_rule->GetType() != CSSRule::kMediaRule) { exception_state.ThrowDOMException( DOMExceptionCode::kNotFoundError, "Cannot remove rule from non-media rule.");
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 4f878d54..044e0ed 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -2038,6 +2038,14 @@ diff.SetNeedsPaintInvalidation(); } + // TODO(1088373): Pixel_WebGLHighToLowPower fails without this. This isn't the + // right way to ensure GPU switching. Investigate and do it in the right way. + if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled() && + !diff.NeedsPaintInvalidation() && IsLayoutView() && Style() && + !Style()->GetFont().IsFallbackValid()) { + diff.SetNeedsPaintInvalidation(); + } + // The answer to layerTypeRequired() for plugins, iframes, and canvas can // change without the actual style changing, since it depends on whether we // decide to composite these elements. When the/ layer status of one of these
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.cc b/third_party/blink/renderer/core/layout/layout_theme_default.cc index 806f976..679b4e0 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_default.cc
@@ -240,6 +240,10 @@ style.SetMinWidth(Length::Fixed(size.Width() * zoom_level)); } +bool LayoutThemeDefault::PopsMenuByReturnKey() const { + return !features::IsFormControlsRefreshEnabled(); +} + bool LayoutThemeDefault::ShouldOpenPickerWithF4Key() const { return true; }
diff --git a/third_party/blink/renderer/core/layout/layout_theme_default.h b/third_party/blink/renderer/core/layout/layout_theme_default.h index 50588077..5347a78 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_default.h +++ b/third_party/blink/renderer/core/layout/layout_theme_default.h
@@ -75,7 +75,7 @@ void AdjustButtonStyle(ComputedStyle&) const override; bool PopsMenuBySpaceKey() const final { return true; } - bool PopsMenuByReturnKey() const final { return true; } + bool PopsMenuByReturnKey() const final; bool PopsMenuByAltDownUpOrF4Key() const override { return true; } bool ShouldOpenPickerWithF4Key() const override;
diff --git a/third_party/blink/renderer/core/loader/lazy_image_helper.cc b/third_party/blink/renderer/core/loader/lazy_image_helper.cc index 2678cc3..444d8c8f 100644 --- a/third_party/blink/renderer/core/loader/lazy_image_helper.cc +++ b/third_party/blink/renderer/core/loader/lazy_image_helper.cc
@@ -74,12 +74,6 @@ if (auto* html_image = DynamicTo<HTMLImageElement>(element)) { LoadingAttributeValue effective_loading_attr = GetLoadingAttributeValue( html_image->FastGetAttribute(html_names::kLoadingAttr)); - // If the 'lazyload' feature policy is enforced, the attribute value - // loading='eager' is considered as 'auto'. - if (effective_loading_attr == LoadingAttributeValue::kEager && - document->IsLazyLoadPolicyEnforced()) { - effective_loading_attr = LoadingAttributeValue::kAuto; - } DCHECK_NE(effective_loading_attr, LoadingAttributeValue::kEager); if (effective_loading_attr == LoadingAttributeValue::kAuto) { deferral_message = DeferralMessage::kLoadEventsDeferred; @@ -128,8 +122,7 @@ } } - if (loading_attr == LoadingAttributeValue::kEager && - !frame.GetDocument()->IsLazyLoadPolicyEnforced()) { + if (loading_attr == LoadingAttributeValue::kEager) { UseCounter::Count(frame.GetDocument(), WebFeature::kLazyLoadImageLoadingAttributeEager); return LazyImageHelper::Eligibility::kDisabled;
diff --git a/third_party/blink/renderer/core/style/BUILD.gn b/third_party/blink/renderer/core/style/BUILD.gn index 9eab35a8..c22bf4f 100644 --- a/third_party/blink/renderer/core/style/BUILD.gn +++ b/third_party/blink/renderer/core/style/BUILD.gn
@@ -81,6 +81,8 @@ "style_inherited_variables.h", "style_initial_data.cc", "style_initial_data.h", + "style_name.h", + "style_name_or_keyword.h", "style_non_inherited_variables.h", "style_offset_rotation.h", "style_path.cc", @@ -114,6 +116,8 @@ "computed_style_test.cc", "filter_operations_test.cc", "style_difference_test.cc", + "style_name_or_keyword_test.cc", + "style_name_test.cc", "style_variables_test.cc", "svg_computed_style_test.cc", ]
diff --git a/third_party/blink/renderer/core/style/style_name.h b/third_party/blink/renderer/core/style/style_name.h new file mode 100644 index 0000000..1604bd1 --- /dev/null +++ b/third_party/blink/renderer/core/style/style_name.h
@@ -0,0 +1,43 @@ +// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" + +namespace blink { + +// Represents any named entity, provided by e.g. <custom-ident> | <string>. +// +// The StyleName will remember whether it came from a <custom-ident> or a +// a <string>, such that it can be serialized accordingly. +class CORE_EXPORT StyleName { + public: + enum class Type { kCustomIdent, kString }; + + StyleName() = default; + explicit StyleName(const AtomicString& value, Type type) + : type_(type), value_(value) {} + + Type GetType() const { return type_; } + + bool IsCustomIdent() const { return type_ == Type::kCustomIdent; } + + const AtomicString& GetValue() const { return value_; } + + bool operator==(const StyleName& other) const { + return type_ == other.type_ && value_ == other.value_; + } + bool operator!=(const StyleName& other) const { return !(*this == other); } + + private: + Type type_ = Type::kString; + AtomicString value_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_H_
diff --git a/third_party/blink/renderer/core/style/style_name_or_keyword.h b/third_party/blink/renderer/core/style/style_name_or_keyword.h new file mode 100644 index 0000000..3f2e99c --- /dev/null +++ b/third_party/blink/renderer/core/style/style_name_or_keyword.h
@@ -0,0 +1,48 @@ +// Copyright 2020 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 THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_OR_KEYWORD_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_OR_KEYWORD_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/css_value_keywords.h" +#include "third_party/blink/renderer/core/style/style_name.h" + +namespace blink { + +class CORE_EXPORT StyleNameOrKeyword { + public: + explicit StyleNameOrKeyword(StyleName name) + : keyword_(CSSValueID::kInvalid), name_(name) {} + explicit StyleNameOrKeyword(CSSValueID keyword) : keyword_(keyword) { + DCHECK_NE(keyword, CSSValueID::kInvalid); + } + + bool IsKeyword() const { return keyword_ != CSSValueID::kInvalid; } + + CSSValueID GetKeyword() const { + DCHECK(IsKeyword()); + return keyword_; + } + + const StyleName& GetName() const { + DCHECK(!IsKeyword()); + return name_; + } + + bool operator==(const StyleNameOrKeyword& other) const { + return keyword_ == other.keyword_ && name_ == other.name_; + } + bool operator!=(const StyleNameOrKeyword& other) const { + return !(*this == other); + } + + private: + CSSValueID keyword_; + StyleName name_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_NAME_OR_KEYWORD_H_
diff --git a/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc b/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc new file mode 100644 index 0000000..0a83044 --- /dev/null +++ b/third_party/blink/renderer/core/style/style_name_or_keyword_test.cc
@@ -0,0 +1,46 @@ +// Copyright 2020 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 "third_party/blink/renderer/core/style/style_name_or_keyword.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(StyleNameOrKeywordTest, StyleName) { + StyleName name_custom_ident("foo", StyleName::Type::kCustomIdent); + StyleName name_string("foo", StyleName::Type::kString); + + EXPECT_FALSE(StyleNameOrKeyword(name_custom_ident).IsKeyword()); + EXPECT_FALSE(StyleNameOrKeyword(name_string).IsKeyword()); + + EXPECT_EQ(name_custom_ident, StyleNameOrKeyword(name_custom_ident).GetName()); + EXPECT_EQ(name_string, StyleNameOrKeyword(name_string).GetName()); +} + +TEST(StyleNameOrKeywordTest, Keyword) { + EXPECT_TRUE(StyleNameOrKeyword(CSSValueID::kAuto).IsKeyword()); + EXPECT_TRUE(StyleNameOrKeyword(CSSValueID::kNone).IsKeyword()); + + EXPECT_EQ(CSSValueID::kAuto, + StyleNameOrKeyword(CSSValueID::kAuto).GetKeyword()); + EXPECT_EQ(CSSValueID::kNone, + StyleNameOrKeyword(CSSValueID::kNone).GetKeyword()); +} + +TEST(StyleNameOrKeywordTest, Equality) { + StyleName name_custom_ident("foo", StyleName::Type::kCustomIdent); + StyleName name_string("foo", StyleName::Type::kString); + + EXPECT_EQ(StyleNameOrKeyword(CSSValueID::kAuto), + StyleNameOrKeyword(CSSValueID::kAuto)); + EXPECT_EQ(StyleNameOrKeyword(name_string), StyleNameOrKeyword(name_string)); + EXPECT_EQ(StyleNameOrKeyword(name_custom_ident), + StyleNameOrKeyword(name_custom_ident)); + EXPECT_NE(StyleNameOrKeyword(name_custom_ident), + StyleNameOrKeyword(name_string)); + EXPECT_NE(StyleNameOrKeyword(CSSValueID::kAuto), + StyleNameOrKeyword(CSSValueID::kNone)); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_name_test.cc b/third_party/blink/renderer/core/style/style_name_test.cc new file mode 100644 index 0000000..86e59ad8 --- /dev/null +++ b/third_party/blink/renderer/core/style/style_name_test.cc
@@ -0,0 +1,54 @@ +// Copyright 2020 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 "third_party/blink/renderer/core/style/style_name.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(StyleNameTest, DefaultConstructor) { + StyleName name; + EXPECT_FALSE(name.IsCustomIdent()); + EXPECT_TRUE(name.GetValue().IsNull()); +} + +TEST(StyleNameTest, Copy) { + StyleName name_string("foo", StyleName::Type::kString); + StyleName name_custom_ident("foo", StyleName::Type::kCustomIdent); + + StyleName name_string_copy1(name_string); + StyleName name_custom_ident_copy1(name_custom_ident); + + StyleName name_string_copy2 = name_string; + StyleName name_custom_ident_copy2 = name_custom_ident; + + EXPECT_EQ(name_string, name_string_copy1); + EXPECT_EQ(name_string, name_string_copy2); + + EXPECT_EQ(name_custom_ident, name_custom_ident_copy1); + EXPECT_EQ(name_custom_ident, name_custom_ident_copy2); +} + +TEST(StyleNameTest, CustomIdent) { + StyleName name("foo", StyleName::Type::kCustomIdent); + EXPECT_TRUE(name.IsCustomIdent()); + EXPECT_EQ("foo", name.GetValue()); +} + +TEST(StyleNameTest, String) { + StyleName name("foo", StyleName::Type::kString); + EXPECT_FALSE(name.IsCustomIdent()); + EXPECT_EQ("foo", name.GetValue()); +} + +TEST(StyleNameTest, Equals) { + EXPECT_EQ(StyleName("foo", StyleName::Type::kString), + StyleName("foo", StyleName::Type::kString)); + EXPECT_NE(StyleName("foo", StyleName::Type::kString), + StyleName("bar", StyleName::Type::kString)); + EXPECT_NE(StyleName("foo", StyleName::Type::kString), + StyleName("foo", StyleName::Type::kCustomIdent)); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc index 9afcc9a..3b1ca42 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -165,14 +165,13 @@ ScriptPromise Bluetooth::getAvailability(ScriptState* script_state, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context || context->IsContextDestroyed()) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } - CHECK(context->IsSecureContext()); - EnsureServiceConnection(context); + CHECK(window_->IsSecureContext()); + EnsureServiceConnection(window_); // Subsequent steps are handled in the browser process. auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -221,16 +220,15 @@ ScriptPromise Bluetooth::getDevices(ScriptState* script_state, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } - AddUnsupportedPlatformConsoleMessage(context); - CHECK(context->IsSecureContext()); + AddUnsupportedPlatformConsoleMessage(window_); + CHECK(window_->IsSecureContext()); - EnsureServiceConnection(context); + EnsureServiceConnection(window_); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); @@ -244,29 +242,24 @@ ScriptPromise Bluetooth::requestDevice(ScriptState* script_state, const RequestDeviceOptions* options, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } - AddUnsupportedPlatformConsoleMessage(context); - CHECK(context->IsSecureContext()); + AddUnsupportedPlatformConsoleMessage(window_); + CHECK(window_->IsSecureContext()); // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. - auto* frame = To<LocalDOMWindow>(context)->GetFrame(); - if (!frame) { - exception_state.ThrowTypeError(kInactiveDocumentError); - return ScriptPromise(); - } - + auto* frame = window_->GetFrame(); + DCHECK(frame); if (!LocalFrame::HasTransientUserActivation(frame)) { exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest); return ScriptPromise(); } - EnsureServiceConnection(context); + EnsureServiceConnection(window_); // In order to convert the arguments from service names and aliases to just // UUIDs, do the following substeps: @@ -347,37 +340,33 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, const BluetoothLEScanOptions* options, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } // Remind developers when they are using Web Bluetooth on unsupported // platforms. - context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + window_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kJavaScript, mojom::ConsoleMessageLevel::kInfo, "Web Bluetooth Scanning is experimental on this platform. See " "https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/" "implementation-status.md")); - CHECK(context->IsSecureContext()); + CHECK(window_->IsSecureContext()); // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. - auto* frame = To<LocalDOMWindow>(context)->GetFrame(); - if (!frame) { - exception_state.ThrowTypeError(kInactiveDocumentError); - return ScriptPromise(); - } - + auto* frame = window_->GetFrame(); + // If !window_->IsContextDestroyed() then GetFrame() should be valid. + DCHECK(frame); if (!LocalFrame::HasTransientUserActivation(frame)) { exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest); return ScriptPromise(); } - EnsureServiceConnection(context); + EnsureServiceConnection(window_); auto scan_options = mojom::blink::WebBluetoothRequestLEScanOptions::New(); ConvertRequestLEScanOptions(options, scan_options, exception_state); @@ -394,7 +383,7 @@ // See https://bit.ly/2S0zRAS for task types. mojo::ReceiverId id = client_receivers_.Add(client.InitWithNewEndpointAndPassReceiver(), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + window_->GetTaskRunner(TaskType::kMiscPlatformAPI)); auto scan_options_copy = scan_options->Clone(); service_->RequestScanningStart( @@ -407,12 +396,11 @@ void Bluetooth::AdvertisingEvent( mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event) { - ExecutionContext* context = - ExecutionContextLifecycleObserver::GetExecutionContext(); - DCHECK(context); - + // client_receivers_ would not be able to send an AdvertisingEvent if the + // context was destroyed because it inherits ContextLifecycleObserver. + DCHECK(!window_->IsContextDestroyed()); BluetoothDevice* bluetooth_device = GetBluetoothDeviceRepresentingDevice( - std::move(advertising_event->device), context); + std::move(advertising_event->device), window_); HeapVector<blink::StringOrUnsignedLong> uuids; for (const String& uuid : advertising_event->uuids) { @@ -462,24 +450,23 @@ } ExecutionContext* Bluetooth::GetExecutionContext() const { - return ExecutionContextLifecycleObserver::GetExecutionContext(); + return window_; } void Bluetooth::Trace(Visitor* visitor) const { visitor->Trace(device_instance_map_); + visitor->Trace(window_); visitor->Trace(client_receivers_); visitor->Trace(service_); EventTargetWithInlineData::Trace(visitor); - ExecutionContextLifecycleObserver::Trace(visitor); PageVisibilityObserver::Trace(visitor); } -Bluetooth::Bluetooth(ExecutionContext* context) - : ExecutionContextLifecycleObserver(context), - PageVisibilityObserver( - To<LocalDOMWindow>(context)->GetFrame()->GetPage()), - client_receivers_(this, context), - service_(context) {} +Bluetooth::Bluetooth(LocalDOMWindow* dom_window) + : PageVisibilityObserver(dom_window->GetFrame()->GetPage()), + window_(dom_window), + client_receivers_(this, dom_window), + service_(dom_window) {} Bluetooth::~Bluetooth() { DCHECK(client_receivers_.empty());
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/third_party/blink/renderer/modules/bluetooth/bluetooth.h index 68fd80a..5940985 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.h +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.h
@@ -24,14 +24,13 @@ class ScriptState; class Bluetooth final : public EventTargetWithInlineData, - public ExecutionContextLifecycleObserver, public PageVisibilityObserver, public mojom::blink::WebBluetoothAdvertisementClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(Bluetooth); public: - explicit Bluetooth(ExecutionContext*); + explicit Bluetooth(LocalDOMWindow*); ~Bluetooth() override; // IDL exposed interface: @@ -57,9 +56,6 @@ // GC void Trace(Visitor*) const override; - // ExecutionContextLifecycleObserver - void ContextDestroyed() override {} - DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived) // PageVisibilityObserver @@ -93,6 +89,8 @@ // Bluetooth device inside a single global object. HeapHashMap<String, Member<BluetoothDevice>> device_instance_map_; + Member<LocalDOMWindow> window_; + HeapMojoAssociatedReceiverSet<mojom::blink::WebBluetoothAdvertisementClient, Bluetooth> client_receivers_;
diff --git a/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc index ab470035..62a4ed1 100644 --- a/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc +++ b/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc
@@ -29,11 +29,11 @@ if (bluetooth_) return bluetooth_.Get(); - if (!GetSupplementable()->GetFrame()) + if (!GetSupplementable()->DomWindow()) return nullptr; - bluetooth_ = MakeGarbageCollected<Bluetooth>( - GetSupplementable()->GetFrame()->GetDocument()->GetExecutionContext()); + bluetooth_ = + MakeGarbageCollected<Bluetooth>(GetSupplementable()->DomWindow()); return bluetooth_.Get(); }
diff --git a/third_party/blink/renderer/modules/font_access/font_metadata.cc b/third_party/blink/renderer/modules/font_access/font_metadata.cc index 4c8b8a5..56f00cf 100644 --- a/third_party/blink/renderer/modules/font_access/font_metadata.cc +++ b/third_party/blink/renderer/modules/font_access/font_metadata.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/font_access/font_metadata.h" #include "base/big_endian.h" +#include "base/metrics/histogram_functions.h" #include "base/sys_byteorder.h" #include "build/build_config.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -13,6 +14,7 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkTypes.h" namespace { @@ -147,6 +149,22 @@ return promise; } +ScriptPromise FontMetadata::blob(ScriptState* script_state) { + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + Thread::Current()->GetTaskRunner()->PostTask( + FROM_HERE, WTF::Bind(&FontMetadata::blobImpl, WrapPersistent(resolver), + postscriptName_)); + + return promise; +} + +void FontMetadata::Trace(blink::Visitor* visitor) const { + ScriptWrappable::Trace(visitor); +} + // static void FontMetadata::getTablesImpl(ScriptPromiseResolver* resolver, const String& postscriptName, @@ -238,8 +256,68 @@ resolver->Resolve(map); } -void FontMetadata::Trace(blink::Visitor* visitor) const { - ScriptWrappable::Trace(visitor); +// static +void FontMetadata::blobImpl(ScriptPromiseResolver* resolver, + const String& postscriptName) { + if (!resolver->GetScriptState()->ContextIsValid()) + return; + + FontDescription description; + scoped_refptr<SimpleFontData> font_data = + FontCache::GetFontCache()->GetFontData(description, + AtomicString(postscriptName)); + if (!font_data) { + auto message = String::Format("The font %s could not be accessed.", + postscriptName.Latin1().c_str()); + ScriptState::Scope scope(resolver->GetScriptState()); + resolver->Reject(V8ThrowException::CreateTypeError( + resolver->GetScriptState()->GetIsolate(), message)); + return; + } + + const SkTypeface* typeface = font_data->PlatformData().Typeface(); + + // On Mac, this will not be as efficient as on other platforms: data from + // tables will be copied and assembled into valid SNFT font data. This is + // because Mac system APIs only return per-table data. + int ttc_index = 0; + std::unique_ptr<SkStreamAsset> stream = typeface->openStream(&ttc_index); + + if (!(stream && stream->getMemoryBase())) { + // TODO(https://crbug.com/1086840): openStream rarely fails, but it happens + // sometimes. A potential remediation is to synthesize a font from tables + // at the cost of memory and throughput. + // For reference, the UMA metric "Blink.Fonts.HarfBuzzFaceZeroCopyAccess" + // indicates that the success rate is close to 100% on all platforms where + // it applies, but failures do happen. + base::UmaHistogramBoolean("Blink.Fonts.DataAccess.StreamCreation", false); + + auto message = String::Format("Font data for %s could not be accessed.", + postscriptName.Latin1().c_str()); + ScriptState::Scope scope(resolver->GetScriptState()); + resolver->Reject(V8ThrowException::CreateTypeError( + resolver->GetScriptState()->GetIsolate(), message)); + return; + } + + base::UmaHistogramBoolean("Blink.Fonts.DataAccess.StreamCreation", true); + wtf_size_t font_byte_size = SafeCast<wtf_size_t>(stream->getLength()); + + // TODO(https://crbug.com/1069900): This copies the font bytes. Lazy load and + // stream the data instead. + Vector<char> bytes(font_byte_size); + size_t returned_size = stream->read(bytes.data(), font_byte_size); + DCHECK_EQ(returned_size, font_byte_size); + + scoped_refptr<RawData> raw_data = RawData::Create(); + bytes.swap(*raw_data->MutableData()); + auto blob_data = std::make_unique<BlobData>(); + blob_data->AppendData(std::move(raw_data)); + blob_data->SetContentType("application/octet-stream"); + + auto* blob = MakeGarbageCollected<Blob>( + BlobDataHandle::Create(std::move(blob_data), font_byte_size)); + resolver->Resolve(blob); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/font_access/font_metadata.h b/third_party/blink/renderer/modules/font_access/font_metadata.h index 40a0b96..c8ba8ef 100644 --- a/third_party/blink/renderer/modules/font_access/font_metadata.h +++ b/third_party/blink/renderer/modules/font_access/font_metadata.h
@@ -46,6 +46,7 @@ ScriptPromise getTables(ScriptState*); ScriptPromise getTables(ScriptState*, const Vector<String>& tables); + ScriptPromise blob(ScriptState*); void Trace(Visitor*) const override; @@ -53,6 +54,8 @@ static void getTablesImpl(ScriptPromiseResolver* resolver, const String& postscriptName, const Vector<String>& tables); + static void blobImpl(ScriptPromiseResolver* resolver, + const String& postscriptName); String postscriptName_; String fullName_; String family_;
diff --git a/third_party/blink/renderer/modules/font_access/font_metadata.idl b/third_party/blink/renderer/modules/font_access/font_metadata.idl index 2371d9ac9..a4ae2c2 100644 --- a/third_party/blink/renderer/modules/font_access/font_metadata.idl +++ b/third_party/blink/renderer/modules/font_access/font_metadata.idl
@@ -12,4 +12,5 @@ readonly attribute USVString fullName; readonly attribute USVString family; [CallWith=ScriptState] Promise<FontTableMap> getTables(optional sequence<ByteString> tables); + [CallWith=ScriptState] Promise<Blob> blob(); };
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc b/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc index 2cd52001..203d76c 100644 --- a/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc +++ b/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc
@@ -40,10 +40,10 @@ std::move(callback)); } -GamepadDispatcher::GamepadDispatcher(ExecutionContext* context) +GamepadDispatcher::GamepadDispatcher(ExecutionContext& context) : // See https://bit.ly/2S0zRAS for task types. - task_runner_(context->GetTaskRunner(TaskType::kMiscPlatformAPI)), - gamepad_haptics_manager_remote_(context) {} + task_runner_(context.GetTaskRunner(TaskType::kMiscPlatformAPI)), + gamepad_haptics_manager_remote_(&context) {} GamepadDispatcher::~GamepadDispatcher() = default;
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h b/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h index bf81f7c..a783694 100644 --- a/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h +++ b/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h
@@ -30,7 +30,7 @@ USING_GARBAGE_COLLECTED_MIXIN(GamepadDispatcher); public: - explicit GamepadDispatcher(ExecutionContext* context); + explicit GamepadDispatcher(ExecutionContext& context); ~GamepadDispatcher() override; void SampleGamepads(device::Gamepads&);
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc index 8bc41ea..f458d6a6f 100644 --- a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc +++ b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc
@@ -58,17 +58,17 @@ namespace blink { // static -GamepadHapticActuator* GamepadHapticActuator::Create(ExecutionContext* context, +GamepadHapticActuator* GamepadHapticActuator::Create(ExecutionContext& context, int pad_index) { return MakeGarbageCollected<GamepadHapticActuator>( context, pad_index, device::GamepadHapticActuatorType::kDualRumble); } GamepadHapticActuator::GamepadHapticActuator( - ExecutionContext* context, + ExecutionContext& context, int pad_index, device::GamepadHapticActuatorType type) - : ExecutionContextClient(context), + : ExecutionContextClient(&context), pad_index_(pad_index), gamepad_dispatcher_(MakeGarbageCollected<GamepadDispatcher>(context)) { SetType(type);
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h index 8636c1e..e9ee53e 100644 --- a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h +++ b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
@@ -26,10 +26,10 @@ USING_GARBAGE_COLLECTED_MIXIN(GamepadHapticActuator); public: - static GamepadHapticActuator* Create(ExecutionContext* context, + static GamepadHapticActuator* Create(ExecutionContext& context, int pad_index); - GamepadHapticActuator(ExecutionContext* context, + GamepadHapticActuator(ExecutionContext& context, int pad_index, device::GamepadHapticActuatorType type); ~GamepadHapticActuator() override;
diff --git a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc index 657e41890..9a8a0aa 100644 --- a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc +++ b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -146,8 +146,7 @@ int pad_index = gamepad.index(); DCHECK_GE(pad_index, 0); if (!vibration_actuators_[pad_index]) { - ExecutionContext* context = DomWindow(); - auto* actuator = GamepadHapticActuator::Create(context, pad_index); + auto* actuator = GamepadHapticActuator::Create(*DomWindow(), pad_index); actuator->SetType(gamepad.GetVibrationActuatorType()); vibration_actuators_[pad_index] = actuator; } @@ -193,7 +192,7 @@ ExecutionContextClient(navigator.DomWindow()), PlatformEventController(*navigator.DomWindow()), gamepad_dispatcher_( - MakeGarbageCollected<GamepadDispatcher>(navigator.DomWindow())) { + MakeGarbageCollected<GamepadDispatcher>(*navigator.DomWindow())) { navigator.DomWindow()->RegisterEventListenerObserver(this); // Fetch |window.performance.timing.navigationStart|. Gamepad timestamps are
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc index 56a25a8d9..77fa17b 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc
@@ -10,6 +10,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "media/base/media_switches.h" #include "media/base/mime_util.h" @@ -588,8 +589,11 @@ MediaCapabilities::PendingCallbackState::PendingCallbackState( ScriptPromiseResolver* resolver, - MediaKeySystemAccess* access) - : resolver(resolver), key_system_access(access) {} + MediaKeySystemAccess* access, + const base::TimeTicks& request_time) + : resolver(resolver), + key_system_access(access), + request_time(request_time) {} void MediaCapabilities::PendingCallbackState::Trace( blink::Visitor* visitor) const { @@ -601,6 +605,8 @@ ScriptState* script_state, const MediaDecodingConfiguration* config, ExceptionState& exception_state) { + const base::TimeTicks request_time = base::TimeTicks::Now(); + if (config->hasKeySystemConfiguration()) { UseCounter::Count( ExecutionContext::From(script_state), @@ -689,7 +695,7 @@ // GetEmeSupport() will call the VideoDecodePerfHistory service after // receiving info about support for the configuration for encrypted content. return GetEmeSupport(script_state, video_codec, video_profile, config, - exception_state); + request_time, exception_state); } bool audio_supported = true; @@ -724,8 +730,8 @@ // undefined. See comment above Promise() in script_promise_resolver.h ScriptPromise promise = resolver->Promise(); - GetPerfInfo(video_codec, video_profile, config->video(), resolver, - nullptr /* access */); + GetPerfInfo(video_codec, video_profile, config->video(), request_time, + resolver, nullptr /* access */); return promise; } @@ -861,6 +867,7 @@ media::VideoCodec video_codec, media::VideoCodecProfile video_profile, const MediaDecodingConfiguration* configuration, + const base::TimeTicks& request_time, ExceptionState& exception_state) { DVLOG(3) << __func__; DCHECK(configuration->hasKeySystemConfiguration()); @@ -984,7 +991,7 @@ script_state, key_system_config->keySystem(), config_vector, WTF::Bind(&MediaCapabilities::GetPerfInfo, WrapPersistent(this), video_codec, video_profile, - WrapPersistent(configuration->video()))); + WrapPersistent(configuration->video()), request_time)); // IMPORTANT: Acquire the promise before potentially synchronously resolving // it in the code that follows. Otherwise the promise returned to JS will be @@ -1002,6 +1009,7 @@ void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec, media::VideoCodecProfile video_profile, const VideoConfiguration* video_config, + const base::TimeTicks& request_time, ScriptPromiseResolver* resolver, MediaKeySystemAccess* access) { ExecutionContext* execution_context = resolver->GetExecutionContext(); @@ -1032,8 +1040,8 @@ const int callback_id = CreateCallbackId(); pending_cb_map_.insert( callback_id, - MakeGarbageCollected<MediaCapabilities::PendingCallbackState>(resolver, - access)); + MakeGarbageCollected<MediaCapabilities::PendingCallbackState>( + resolver, access, request_time)); if (base::FeatureList::IsEnabled(media::kMediaLearningSmoothnessExperiment)) { GetPerfInfo_ML(execution_context, callback_id, video_codec, video_profile, @@ -1092,6 +1100,7 @@ if (!pending_cb->db_is_power_efficient.has_value()) return; + // Both db_* fields should be set simultaneously by the DB callback. DCHECK(pending_cb->db_is_smooth.has_value()); @@ -1128,6 +1137,21 @@ info->setSmooth(*pending_cb->db_is_smooth); } + const base::TimeDelta process_time = + base::TimeTicks::Now() - pending_cb->request_time; + UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video", + process_time); + + // Record another time in the appropriate subset, either clear or encrypted + // content. + if (pending_cb->key_system_access) { + UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video.Encrypted", + process_time); + } else { + UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video.Clear", + process_time); + } + pending_cb->resolver->Resolve(std::move(info)); pending_cb_map_.erase(callback_id); }
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h index d98f3780f..a590454 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h
@@ -50,7 +50,8 @@ class PendingCallbackState : public GarbageCollected<PendingCallbackState> { public: PendingCallbackState(ScriptPromiseResolver* resolver, - MediaKeySystemAccess* access); + MediaKeySystemAccess* access, + const base::TimeTicks& request_time); virtual void Trace(blink::Visitor* visitor) const; Member<ScriptPromiseResolver> resolver; @@ -59,6 +60,7 @@ base::Optional<bool> is_nnr_prediction_smooth; base::Optional<bool> db_is_smooth; base::Optional<bool> db_is_power_efficient; + base::TimeTicks request_time; }; // Lazily binds remote LearningTaskControllers for ML smoothness predictions @@ -73,12 +75,14 @@ media::VideoCodec, media::VideoCodecProfile, const MediaDecodingConfiguration*, + const base::TimeTicks& request_time, ExceptionState&); // Gets perf info from VideoDecodePerrHistory DB. Will optionally kick off // parallel request to GetPerfInfo_ML() when learning experiment is enabled. void GetPerfInfo(media::VideoCodec, media::VideoCodecProfile, const VideoConfiguration*, + const base::TimeTicks& request_time, ScriptPromiseResolver*, MediaKeySystemAccess*);
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc index ed1b81a..4405e524 100644 --- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc +++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -47,69 +47,6 @@ #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" -namespace { - -enum class RendererReloadAction { - KEEP_RENDERER, - REMOVE_RENDERER, - NEW_RENDERER -}; - -bool IsPlayableTrack(blink::MediaStreamComponent* component) { - return component && component->Source() && - component->Source()->GetReadyState() != - blink::MediaStreamSource::kReadyStateEnded; -} - -const char* LoadTypeToString(blink::WebMediaPlayer::LoadType type) { - switch (type) { - case blink::WebMediaPlayer::kLoadTypeURL: - return "URL"; - case blink::WebMediaPlayer::kLoadTypeMediaSource: - return "MediaSource"; - case blink::WebMediaPlayer::kLoadTypeMediaStream: - return "MediaStream"; - } -} - -const char* ReadyStateToString(blink::WebMediaPlayer::ReadyState state) { - switch (state) { - case blink::WebMediaPlayer::kReadyStateHaveNothing: - return "HaveNothing"; - case blink::WebMediaPlayer::kReadyStateHaveMetadata: - return "HaveMetadata"; - case blink::WebMediaPlayer::kReadyStateHaveCurrentData: - return "HaveCurrentData"; - case blink::WebMediaPlayer::kReadyStateHaveFutureData: - return "HaveFutureData"; - case blink::WebMediaPlayer::kReadyStateHaveEnoughData: - return "HaveEnoughData"; - } -} - -const char* NetworkStateToString(blink::WebMediaPlayer::NetworkState state) { - switch (state) { - case blink::WebMediaPlayer::kNetworkStateEmpty: - return "Empty"; - case blink::WebMediaPlayer::kNetworkStateIdle: - return "Idle"; - case blink::WebMediaPlayer::kNetworkStateLoading: - return "Loading"; - case blink::WebMediaPlayer::kNetworkStateLoaded: - return "Loaded"; - case blink::WebMediaPlayer::kNetworkStateFormatError: - return "FormatError"; - case blink::WebMediaPlayer::kNetworkStateNetworkError: - return "NetworkError"; - case blink::WebMediaPlayer::kNetworkStateDecodeError: - return "DecodeError"; - } -} - -constexpr base::TimeDelta kForceBeginFramesTimeout = - base::TimeDelta::FromSeconds(1); -} // namespace - namespace WTF { template <> @@ -128,6 +65,69 @@ namespace blink { +namespace { + +enum class RendererReloadAction { + KEEP_RENDERER, + REMOVE_RENDERER, + NEW_RENDERER +}; + +bool IsPlayableTrack(MediaStreamComponent* component) { + return component && component->Source() && + component->Source()->GetReadyState() != + MediaStreamSource::kReadyStateEnded; +} + +const char* LoadTypeToString(WebMediaPlayer::LoadType type) { + switch (type) { + case WebMediaPlayer::kLoadTypeURL: + return "URL"; + case WebMediaPlayer::kLoadTypeMediaSource: + return "MediaSource"; + case WebMediaPlayer::kLoadTypeMediaStream: + return "MediaStream"; + } +} + +const char* ReadyStateToString(WebMediaPlayer::ReadyState state) { + switch (state) { + case WebMediaPlayer::kReadyStateHaveNothing: + return "HaveNothing"; + case WebMediaPlayer::kReadyStateHaveMetadata: + return "HaveMetadata"; + case WebMediaPlayer::kReadyStateHaveCurrentData: + return "HaveCurrentData"; + case WebMediaPlayer::kReadyStateHaveFutureData: + return "HaveFutureData"; + case WebMediaPlayer::kReadyStateHaveEnoughData: + return "HaveEnoughData"; + } +} + +const char* NetworkStateToString(WebMediaPlayer::NetworkState state) { + switch (state) { + case WebMediaPlayer::kNetworkStateEmpty: + return "Empty"; + case WebMediaPlayer::kNetworkStateIdle: + return "Idle"; + case WebMediaPlayer::kNetworkStateLoading: + return "Loading"; + case WebMediaPlayer::kNetworkStateLoaded: + return "Loaded"; + case WebMediaPlayer::kNetworkStateFormatError: + return "FormatError"; + case WebMediaPlayer::kNetworkStateNetworkError: + return "NetworkError"; + case WebMediaPlayer::kNetworkStateDecodeError: + return "DecodeError"; + } +} + +constexpr base::TimeDelta kForceBeginFramesTimeout = + base::TimeDelta::FromSeconds(1); +} // namespace + #if defined(OS_WIN) // Since we do not have native GMB support in Windows, using GMBs can cause a // CPU regression. This is more apparent and can have adverse affects in lower @@ -1336,9 +1336,8 @@ } void WebMediaPlayerMS::SendLogMessage(const WTF::String& message) const { - blink::WebRtcLogMessage( - "WMPMS::" + message.Utf8() + - String::Format(" [delegate_id=%d]", delegate_id_).Utf8()); + WebRtcLogMessage("WMPMS::" + message.Utf8() + + String::Format(" [delegate_id=%d]", delegate_id_).Utf8()); } std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata>
diff --git a/third_party/blink/renderer/modules/notifications/notification_data.cc b/third_party/blink/renderer/modules/notifications/notification_data.cc index 5028807..01e03aa 100644 --- a/third_party/blink/renderer/modules/notifications/notification_data.cc +++ b/third_party/blink/renderer/modules/notifications/notification_data.cc
@@ -78,11 +78,15 @@ if (options->hasBadge() && !options->badge().IsEmpty()) notification_data->badge = CompleteURL(context, options->badge()); - VibrationController::VibrationPattern vibration_pattern = - VibrationController::SanitizeVibrationPattern(options->vibrate()); + VibrationController::VibrationPattern vibration_pattern; + if (options->hasVibrate()) { + vibration_pattern = + VibrationController::SanitizeVibrationPattern(options->vibrate()); + } notification_data->vibration_pattern = Vector<int32_t>(); notification_data->vibration_pattern->Append(vibration_pattern.data(), vibration_pattern.size()); + notification_data->timestamp = options->hasTimestamp() ? static_cast<double>(options->timestamp()) : base::Time::Now().ToDoubleT() * 1000.0; @@ -90,7 +94,9 @@ notification_data->silent = options->silent(); notification_data->require_interaction = options->requireInteraction(); - if (options->hasData()) { + // TODO(crbug.com/1070871, crbug.com/1070964): |data| member has a null value + // as a default value, and we don't need |hasData()| check actually. + if (options->hasData() && !options->data().IsNull()) { const ScriptValue& data = options->data(); v8::Isolate* isolate = data.GetIsolate(); DCHECK(isolate->InContext());
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index be8c341..f75979e 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -688,4 +688,10 @@ RuntimeEnabledFeatures::SetTransformInteropEnabled(enable); } +void WebRuntimeFeatures::EnableVideoWakeLockOptimisationHiddenMuted( + bool enable) { + RuntimeEnabledFeatures::SetVideoWakeLockOptimisationHiddenMutedEnabled( + enable); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc index cf987ea..a8659c7 100644 --- a/third_party/blink/renderer/platform/fonts/font_fallback_list.cc +++ b/third_party/blink/renderer/platform/fonts/font_fallback_list.cc
@@ -97,7 +97,10 @@ } bool FontFallbackList::ShouldSkipDrawing() const { - DCHECK(IsValid()); + // The DCHECK hit will be fixed by the runtime enabled feature below, so we + // don't fix it in the legacy code paths. + DCHECK(IsValid() || !RuntimeEnabledFeatures:: + CSSReducedFontLoadingLayoutInvalidationsEnabled()); if (!has_loading_fallback_) return false;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index ab475bd..706e8b0 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -557,6 +557,14 @@ status: "stable", depends_on: ["CSSCascade"], }, + // Support for declarative parts of scroll-animations-1, i.e. + // the animation-timeline property and the @scroll-timeline rule. + // + // https://drafts.csswg.org/scroll-animations-1/#animation-timeline + // https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule + { + name: "CSSScrollTimeline" + }, { name: "CSSSnapSize", status: "experimental", @@ -1604,7 +1612,7 @@ { name: "ScrollTimeline", status: "experimental", - implied_by: ['AnimationWorklet'] + implied_by: ['AnimationWorklet', 'CSSScrollTimeline'] }, // Implements documentElement.scrollTop/Left and bodyElement.scrollTop/Left // as per the spec, matching other Web engines. @@ -1861,6 +1869,10 @@ name: "VideoRotateToFullscreen", }, { + name: "VideoWakeLockOptimisationHiddenMuted", + status: "stable", + }, + { name: "VirtualKeyboard", status: "test", },
diff --git a/third_party/blink/web_tests/FlagExpectations/composite-after-paint b/third_party/blink/web_tests/FlagExpectations/composite-after-paint index ed8abcb..9a5c0774 100644 --- a/third_party/blink/web_tests/FlagExpectations/composite-after-paint +++ b/third_party/blink/web_tests/FlagExpectations/composite-after-paint
@@ -35,8 +35,6 @@ external/wpt/paint-timing/fcp-only/fcp-opacity.html [ Skip ] external/wpt/paint-timing/fcp-only/fcp-pseudo-element-opacity.html [ Skip ] -crbug.com/1090431 external/wpt/html/user-activation/message-event-activation-api-iframe-cross-origin.sub.tentative.html [ Timeout ] - # Can't rebaseline because the file path is too long. virtual/compositor_threaded_scrollbar_scrolling/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index acc8ef6e..c547427 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1277,8 +1277,14 @@ crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-script-001.tentative.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-bold-italic-001.tentative.html [ Failure ] crbug.com/626703 external/wpt/css/css-text/text-transform/math/text-transform-math-sans-serif-001.tentative.html [ Failure ] -crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-window.html [ Skip ] -crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-workers.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-window-enumeration.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-window-getTables.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-window-getTables-large-fonts.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-window-blob.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-workers-enumeration.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-workers-getTables.html [ Skip ] +crbug.com/1043295 [ Fuchsia ] virtual/font-access/http/tests/font-access/font-access-workers-blob.html [ Skip ] +crbug.com/1087671 [ Mac ] virtual/font-access/http/tests/font-access/font-access-window-getTables-large-fonts.html [ Skip ] # ====== Style team owned tests from here ====== @@ -5831,10 +5837,6 @@ # the inspector-protocol/media tests only work in the virtual test environment. crbug.com/1074129 inspector-protocol/media/media-player.js [ TIMEOUT ] -# Sheriff 2020-04-29 -crbug.com/1076467 [ Mac ] virtual/font-access/http/tests/font-access/font-access-workers.html [ Pass Timeout Crash ] -crbug.com/1076467 [ Mac ] virtual/font-access/http/tests/font-access/font-access-window.html [ Pass Timeout Crash ] - # Sheriff 2020-04-30 crbug.com/1068681 fast/peerconnection/RTCPeerConnection-insertable-streams.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 48ea662e..42c7002d 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -416,12 +416,6 @@ "--disable-blink-features=RestrictAutomaticLazyImageLoadingToDataSaver"] }, { - "prefix" : "lazyload-policy", - "bases": ["external/wpt/feature-policy/experimental-features/lazyload"], - "args": ["--enable-blink-features=LazyFrameLoading,AutomaticLazyFrameLoading,LazyImageLoading,AutomaticLazyImageLoading", - "--disable-blink-features=RestrictAutomaticLazyFrameLoadingToDataSaver,RestrictAutomaticLazyImageLoadingToDataSaver"] - }, - { "prefix" : "autoupgrade-optionally-blockable-mixed-content", "bases": ["http/tests/mixed-autoupgrade/optionally"], "args": ["--enable-features=AutoupgradeMixedContent"] @@ -655,6 +649,11 @@ "args": ["--enable-blink-features=CSSModules"] }, { + "prefix": "css-scroll-timeline", + "bases": ["external/wpt/scroll-animations/css"], + "args": ["--enable-blink-features=CSSScrollTimeline"] + }, + { "prefix": "out-of-blink-frame-ancestors-disabled", "bases": ["external/wpt/content-security-policy/frame-ancestors", "external/wpt/portals/csp"], "args": ["--disable-features=OutOfBlinkFrameAncestors"]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/at-property-cssom.html b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/at-property-cssom.html index 5a0ef9f5..46671fed 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/at-property-cssom.html +++ b/third_party/blink/web_tests/external/wpt/css/css-properties-values-api/at-property-cssom.html
@@ -55,8 +55,8 @@ <script> function find_at_property_rule(name) { - for (let rule of document.styleSheets[0].cssRules) { - if (rule.type != CSSRule.PROPERTY_RULE) + for (let rule of document.styleSheets[0].cssRules) { + if (rule.constructor.name != "CSSPropertyRule") continue; if (rule.name == name) return rule; @@ -120,6 +120,13 @@ test_css_text('--inherits-only', '@property --inherits-only { inherits: true; }'); test_css_text('--initial-value-only', '@property --initial-value-only { initial-value: red; }'); +// CSSRule.type + +test(() => { + let rule = find_at_property_rule('--valid'); + assert_equals(rule.type, 0); +}, 'CSSRule.type returns 0'); + // CSSPropertyRule.name test_name('--valid');
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html deleted file mode 100644 index e5bb5d3..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html +++ /dev/null
@@ -1,57 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>Verify behavior of 'loading' attribute state 'eager' when the feature policy 'lazyload' is - disabled. -</title> -<link rel="stylesheet" href="/feature-policy/experimental-features/resources/lazyload-image.css"> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> -<style> -body { - width: 100%; - height: 100%; -} - -img { - width: 200px; - height: 200px; - border: solid 1px black; -} - -#image-container { - position: absolute; - top: 10000px; -} -</style> -<body> - <p>Image inserted further below.</p> - <div id="image-container"> - <img id="eager" loading="eager" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img> - <img id="auto" lazyload="auto" src="http://{{hosts[alt][www2]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img> - </div> - <script> - var img_eager = document.getElementById("eager"); - var img_auto = document.getElementById("auto"); - [window, img_eager, img_auto].forEach((target) => { - target.load_complete = wait_for_load(target).then(() => target.did_load = true ); - }); - - function same_load_state() { - return img_eager.did_load === img_auto.did_load; - } - - // Verifies that "eager" and "auto" behave the same for out-of-view images. - promise_test(async(t) => { - await window.load_complete; - assert_true(same_load_state(), "Expected same loading state for both images."); - }, "When the 'lazyload' feature is disabled, lazyload=EAGER and lazyload=AUTO behave the same."); - - // Verifies that images with attributes "eager" and "auto" load after the images get into view. - promise_test(async(t) => { - document.getElementById("image-container").scrollIntoView(); - await img_eager.load_complete; - await img_auto.load_complete; - }, "Sanity-check: Verify that all images load after they are scrolled into view."); - </script> -</body>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html.headers deleted file mode 100644 index 7974815..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-image-tentative.sub.html.headers +++ /dev/null
@@ -1,2 +0,0 @@ -Feature-Policy: lazyload 'none' -Cache-Control: no-cache, no-store, max-age=0
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html deleted file mode 100644 index 2ffcba71..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html +++ /dev/null
@@ -1,93 +0,0 @@ -<!DOCTYPE html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> -<style> -html, body { - height: 100%; - width: 100%; -} - -iframe { - width: 400px; - height: 400px; - margin: 10px; -} - -.spacer { - width: 100%; - height: 10000px; -} -</style> -<div class="spacer"></div> -<script> - let cross_origin_url = - "http://{{hosts[alt][www]}}:{{ports[http][0]}}/" + - "feature-policy/experimental-features/resources/lazyload-contents.html"; - - let load_timeout = 600; // ms - let expected_timeout_msg = false; - - window.scrollTo(0, 0); - - // Sanity-check: Make sure loading='lazy' works as intended. - promise_test(async(t) => { - // Add a frame with loading="lazy". - let frame_lazy = createIframe(document.body, { - id: "LAZY", - loading: "lazy", - src: `${cross_origin_url}?id=LAZY` - }); - // Sanity-check: The frame is not visible. - assert_greater_than( - frame_lazy.getBoundingClientRect().top, - window.innerHeight * 2, - "Unexpected position for <iframe> with ID 'LAZY'."); - let msg_or_timeout_attr_lazy = - await waitForMessageOrTimeout(t, "LAZY", load_timeout); - assert_equals(msg_or_timeout_attr_lazy, - expected_timeout_msg, - "With loading='lazy', the frame should not load."); - }, "Sanity-check: Contents do not load immediately (no eager-loading) " + - "when the loading attribute is 'lazy' and frame is in viewport."); - - - // Verify that when 'lazyload' policy is disabled, loading='eager' and - // loading='auto' behave the same. - promise_test(async(t) => { - // Add a frame with loading="eager". - let frame_lazy = createIframe(document.body, { - id: "EAGER", - loading: "eager", - src: `${cross_origin_url}?id=EAGER` - }); - // Sanity-check: The frame is not visible. - assert_greater_than( - frame_lazy.getBoundingClientRect().top, - window.innerHeight * 2, - "Unexpected position for <iframe> with ID 'EAGER'."); - let msg_or_timeout_attr_eager = - await waitForMessageOrTimeout(t, "EAGER", load_timeout); - - // Now do the same for loading='auto'. - let frame_auto = createIframe(document.body, { - id: "AUTO", - loading: "auto", - src: `${cross_origin_url}?id=AUTO` - }); - // Sanity-check: The frame is not visible. - assert_greater_than( - frame_lazy.getBoundingClientRect().top, - window.innerHeight * 2, - "Unexpected position for <iframe> with ID 'AUTO'."); - let msg_or_timeout_attr_auto = - await waitForMessageOrTimeout(t, "AUTO", load_timeout); - - // The result should be the same. - assert_equals( - msg_or_timeout_attr_eager, - msg_or_timeout_attr_auto, - "loading='eager' not treated as 'auto'."); - }, "When 'lazyload' feature is disabled, a frame cannot avoid lazyloading " + - "by setting 'loading' attribute to 'eager'"); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html.headers deleted file mode 100644 index d0bac47..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-disabled-tentative.sub.html.headers +++ /dev/null
@@ -1 +0,0 @@ -Feature-Policy: lazyload 'none'
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html deleted file mode 100644 index 8983762..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html +++ /dev/null
@@ -1,45 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>Verify behavior of 'lazyload' attribute state 'eager' when the feature policy 'lazyload' is - enabled. -</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> -<style> -body { - width: 100%; - height: 100%; -} - -img { - width: 200px; - height: 200px; - border: solid 1px black; -} - -#image-container { - position: absolute; - top: 10000px; -} -</style> -<body> - <p>Image inserted further below.</p> - <div id="image-container"> - <img loading="eager" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"></img> - </div> - <script> - var img = document.querySelector("img"); - - [img, window].forEach((target) => { - target.load_complete = wait_for_load(target).then(() => target.did_load = true ); - }); - - // Sanity-check: Verify that when feature-policy 'lazyload' is enabled, the attribute - // loading='eager' works as expected (images load immediately). - promise_test( async(t) => { - await window.load_complete; - assert_true(img.did_load, "Image should have loaded."); - }, "When feature is enabled, loading=eager works as expected."); - </script> -</body>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html deleted file mode 100644 index d1171b5d..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html +++ /dev/null
@@ -1,77 +0,0 @@ -<!DOCTYPE html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> -<style> -html, body { - height: 100%; - width: 100%; -} - -iframe { - width: 400px; - height: 400px; - margin: 10px; -} - -.spacer { - width: 100%; - height: 10000px; -} -</style> -<div class="spacer"></div> -<script> - let cross_origin_url = - "http://{{hosts[alt][www]}}:{{ports[http][0]}}/" + - "feature-policy/experimental-features/resources/lazyload-contents.html"; - - let load_timeout = 600; // ms - let expected_timeout_msg = false; - let expected_load_msg = "This page is lazyloaded."; - - window.scrollTo(0, 0); - - // Sanity-check: Make sure loading='lazy' works as intended. - promise_test(async(t) => { - // Add a frame with loading="lazy". - let frame_on = createIframe(document.body, { - id: "ON", - loading: "lazy", - src: `${cross_origin_url}?id=ON` - }); - // Sanity-check: The frame is not visible. - assert_greater_than( - frame_on.getBoundingClientRect().top, - window.innerHeight * 2, - "Unexpected position for <iframe> with ID 'ON'."); - let msg_or_timeout_attr_on = - await waitForMessageOrTimeout(t, "ON", load_timeout); - assert_equals(msg_or_timeout_attr_on, - expected_timeout_msg, - "With loading='lazy', the frame should not load."); - }, "Sanity-check: Contents do not load immediately (no eager-loading) " + - "when the loading attribute is 'lazy' and frame is in viewport."); - - // When feature is enabled, a frame can turn off lazy loading by setting the - // attribute to 'eager'. - promise_test(async(t) => { - // Add a frame with loading="eager". - let frame_off = createIframe(document.body, { - id: "OFF", - loading: "eager", - src: `${cross_origin_url}?id=OFF` - }); - // Sanity-check: The frame is not visible. - assert_greater_than( - frame_off.getBoundingClientRect().top, - window.innerHeight * 2, - "Unexpected position for <iframe> with ID 'OFF'."); - let msg_or_timeout_attr_off = - await waitForMessageOrTimeout(t, "OFF", load_timeout); - - assert_equals(msg_or_timeout_attr_off, - expected_load_msg, - "With loading='eager', the frame should load."); - }, "When 'lazyload' feature is enabled, a frame can avoid lazyloading by " + - "setting 'loading' attribute to 'eager'"); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.headers deleted file mode 100644 index 83b744e..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.headers +++ /dev/null
@@ -1 +0,0 @@ -Feature-Policy: lazyload *
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-image-loading-lazy-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-image-loading-lazy-tentative.sub.html deleted file mode 100644 index 8f1ef19..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/lazyload-image-loading-lazy-tentative.sub.html +++ /dev/null
@@ -1,49 +0,0 @@ -<!doctype html> -<meta charset=utf-8> -<title>Verify behavior of 'loading' attribute state 'LAZY' (sanity-check for lazyload policy tests). -</title> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> -<style> -body { - width: 100%; - height: 100%; -} - -img { - width: 200px; - height: 200px; - border: solid 1px black; -} - -#image-container { - position: absolute; - top: 10000px; -} -</style> -<body> - <p>Image inserted further below.</p> - <div id="image-container"> - <img loading="lazy" src="http://{{hosts[alt][www1]}}:{{ports[http][0]}}/feature-policy/experimental-features/resources/lazyload.png"/> - </div> - <script> - var img = document.querySelector("img"); - - [img, window].forEach((target) => { - target.did_load = false; - target.load_complete = wait_for_load(target).then(() => target.did_load = true ); - }); - - // Verify that when feature-policy 'lazyload' is enabled, the loading - // attribute value 'LAZY' works as expected (images load only when scrolled - // down). - promise_test( async(t) => { - await window.load_complete; - assert_false(img.did_load, "Out-of-viewport image should not have loaded."); - img.scrollIntoView(); - await img.load_complete; - }, "Verify 'loading' attribute state 'lazy' works as expected: image loads only when in " + - "viewport."); - </script> -</body>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html deleted file mode 100644 index fe24963..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html +++ /dev/null
@@ -1,52 +0,0 @@ -<!DOCTYPE html> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="/feature-policy/experimental-features/resources/common.js"></script> -<style> -html, body { - height: 100%; - width: 100%; -} - -iframe { - width: 400px; - height: 400px; - margin: 10px; -} - -.spacer { - width: 100%; - height: 10000px; -} -</style> -<div class="spacer"></div> -<script> - let load_timeout = 600; // ms - let expected_timeout_msg = false; - - let cross_origin_url = - "http://{{hosts[alt][www]}}:{{ports[http][0]}}/" + - "feature-policy/experimental-features/resources/lazyload-contents.html"; - - window.scrollTo(0, 0); - - // Verify that when 'loading-frame-default-eager' policy is disabled, the - // loading attribute "auto" leads to lazy loading. - promise_test(async(t) => { - let frame_loading_auto = createIframe(document.body, { - id: "auto", - // Sets the "loading" attribute to "auto". - loading: "auto", - src: `${cross_origin_url}?id=auto` - }); - // Sanity-check: The frame is not visible. - assert_greater_than( - frame_loading_auto.getBoundingClientRect().top, - window.innerHeight * 2, - "Unexpected position for <iframe> with ID 'auto'."); - let msg_or_timeout = - await waitForMessageOrTimeout(t, "auto", load_timeout); - assert_false(msg_or_timeout, "Expected the frame not to load."); - }, "When 'loading-frame-default-eager' feature is disabled, a frame with " + - "'loading attribute 'auto' will be lazily loaded."); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html.headers deleted file mode 100644 index 8cba4d2..0000000 --- a/third_party/blink/web_tests/external/wpt/feature-policy/experimental-features/lazyload/loading-frame-default-eager-disabled-tentative.sub.html.headers +++ /dev/null
@@ -1 +0,0 @@ -Feature-Policy: loading-frame-default-eager 'none'
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html new file mode 100644 index 0000000..a3579eee --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html
@@ -0,0 +1,3 @@ +<!doctype html> +<title>Test reference</title> +<iframe src="/images/green.png"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html new file mode 100644 index 0000000..973da08 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html
@@ -0,0 +1,6 @@ +<!doctype html> +<title>Rendering of iframe element with src attribute from another domain</title> +<link rel="match" href="cross-domain-iframe.sub-ref.html"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules"> +<meta name="assert" content="Checks that iframe content is correctly rendered even if it is retrieved from a different domain."> +<iframe src="http://{{domains[www1]}}:{{ports[http][0]}}/images/green.png"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html new file mode 100644 index 0000000..66c564c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-template-element/template-element/template-content-in-inactive-document-crash.html
@@ -0,0 +1,7 @@ +<iframe id="i"></iframe> +<script> +var t = i.contentDocument.createElement("template"); +i.contentDocument.documentElement.appendChild(t); +i.remove(); +t.content; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html new file mode 100644 index 0000000..89c56d1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/scripting-1/the-template-element/template-element/template-content-move-to-inactive-document-crash.html
@@ -0,0 +1,7 @@ +<div id="d"> +<iframe id="i"></iframe> +<template id="t"> </template> +</div> +<script> +i.contentDocument.documentElement.appendChild(d); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-computed-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-computed-expected.txt new file mode 100644 index 0000000..8ce545a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-computed-expected.txt
@@ -0,0 +1,25 @@ +This is a testharness.js-based test. +FAIL Property animation-timeline value 'initial' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'inherit' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'unset' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'revert' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'auto' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'none' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'auto, auto' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'none, none' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'auto, none' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'none, auto' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"test"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"none"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"auto"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"initial"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"inherit"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"unset"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value '"revert"' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'test' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'test1, test2' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL Property animation-timeline value 'test1, "test2", none, test3, auto' assert_true: animation-timeline doesn't seem to be supported in the computed style expected true got false +FAIL The animation-timeline property shows up in CSSStyleDeclaration enumeration assert_not_equals: got disallowed value -1 +FAIL The animation-timeline property shows up in CSSStyleDeclaration.cssText assert_not_equals: got disallowed value -1 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-computed.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-computed.html new file mode 100644 index 0000000..02836d7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-computed.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#animation-timeline"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/computed-testcommon.js"></script> +</head> +<style> + #outer { animation-timeline: foo; } + #target { animation-timeline: bar; } +</style> +<div id="outer"> + <div id="target"></div> +</div> +<script> +test_computed_value('animation-timeline', 'initial', 'auto'); +test_computed_value('animation-timeline', 'inherit', 'foo'); +test_computed_value('animation-timeline', 'unset', 'auto'); +test_computed_value('animation-timeline', 'revert', 'auto'); +test_computed_value('animation-timeline', 'auto'); +test_computed_value('animation-timeline', 'none'); +test_computed_value('animation-timeline', 'auto, auto'); +test_computed_value('animation-timeline', 'none, none'); +test_computed_value('animation-timeline', 'auto, none'); +test_computed_value('animation-timeline', 'none, auto'); +test_computed_value('animation-timeline', '"test"'); +test_computed_value('animation-timeline', '"none"'); +test_computed_value('animation-timeline', '"auto"'); +test_computed_value('animation-timeline', '"initial"'); +test_computed_value('animation-timeline', '"inherit"'); +test_computed_value('animation-timeline', '"unset"'); +test_computed_value('animation-timeline', '"revert"'); +test_computed_value('animation-timeline', 'test'); +test_computed_value('animation-timeline', 'test1, test2'); +test_computed_value('animation-timeline', 'test1, "test2", none, test3, auto'); + +test(() => { + let style = getComputedStyle(document.getElementById('target')); + assert_not_equals(Array.from(style).indexOf('animation-timeline'), -1); +}, 'The animation-timeline property shows up in CSSStyleDeclaration enumeration'); + +test(() => { + let style = getComputedStyle(document.getElementById('target')); + assert_not_equals(style.cssText.indexOf('animation-timeline'), -1); +}, 'The animation-timeline property shows up in CSSStyleDeclaration.cssText'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt new file mode 100644 index 0000000..0af056b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL The animation-timeline property may not be used in keyframes assert_equals: expected (string) "bar" but got (undefined) undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html new file mode 100644 index 0000000..bdf40e0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-in-keyframe.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#animation-timeline"> +<link rel="help" href="https://drafts.csswg.org/css-animations-1/#keyframes"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<style> + @keyframes test { + from { width: 100px; animation-timeline: foo; } + to { width: 100px: animation-timeline: foo; } + } + #target { + width: 50px; + animation-timeline: bar; + animation-name: test; + animation-duration: 1s; + animation-play-state: paused; + } +</style> +<div id="target"></div> +<script> +test(() => { + let style = getComputedStyle(document.getElementById('target')); + // Checking 'width' verifies that the animation is applied at all. + assert_equals(style.width, '100px'); + assert_equals(style.animationTimeline, 'bar'); +}, 'The animation-timeline property may not be used in keyframes'); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-parsing-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-parsing-expected.txt new file mode 100644 index 0000000..dced00e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-parsing-expected.txt
@@ -0,0 +1,30 @@ +This is a testharness.js-based test. +FAIL e.style['animation-timeline'] = "initial" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "inherit" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "unset" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "revert" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "auto" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "none" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "auto, auto" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "none, none" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "auto, none" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "none, auto" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"test\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"none\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"auto\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"initial\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"inherit\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"unset\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "\"revert\"" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "test" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "test1, test2" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['animation-timeline'] = "test1, \"test2\", none, test3, auto" should set the property value assert_not_equals: property should be set got disallowed value "" +PASS e.style['animation-timeline'] = "10px" should not set the property value +PASS e.style['animation-timeline'] = "auto auto" should not set the property value +PASS e.style['animation-timeline'] = "none none" should not set the property value +PASS e.style['animation-timeline'] = "foo bar" should not set the property value +PASS e.style['animation-timeline'] = "\"foo\" \"bar\"" should not set the property value +PASS e.style['animation-timeline'] = "rgb(1, 2, 3)" should not set the property value +PASS e.style['animation-timeline'] = "#fefefe" should not set the property value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-parsing.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-parsing.html new file mode 100644 index 0000000..8fac81e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-timeline-parsing.html
@@ -0,0 +1,37 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/scroll-animations-1/#animation-timeline"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<div id="target"></div> +<script> +test_valid_value('animation-timeline', 'initial'); +test_valid_value('animation-timeline', 'inherit'); +test_valid_value('animation-timeline', 'unset'); +test_valid_value('animation-timeline', 'revert'); +test_valid_value('animation-timeline', 'auto'); +test_valid_value('animation-timeline', 'none'); +test_valid_value('animation-timeline', 'auto, auto'); +test_valid_value('animation-timeline', 'none, none'); +test_valid_value('animation-timeline', 'auto, none'); +test_valid_value('animation-timeline', 'none, auto'); +test_valid_value('animation-timeline', '"test"'); +test_valid_value('animation-timeline', '"none"'); +test_valid_value('animation-timeline', '"auto"'); +test_valid_value('animation-timeline', '"initial"'); +test_valid_value('animation-timeline', '"inherit"'); +test_valid_value('animation-timeline', '"unset"'); +test_valid_value('animation-timeline', '"revert"'); +test_valid_value('animation-timeline', 'test'); +test_valid_value('animation-timeline', 'test1, test2'); +test_valid_value('animation-timeline', 'test1, "test2", none, test3, auto'); + +test_invalid_value('animation-timeline', '10px'); +test_invalid_value('animation-timeline', 'auto auto'); +test_invalid_value('animation-timeline', 'none none'); +test_invalid_value('animation-timeline', 'foo bar'); +test_invalid_value('animation-timeline', '"foo" "bar"'); +test_invalid_value('animation-timeline', 'rgb(1, 2, 3)'); +test_invalid_value('animation-timeline', '#fefefe'); +</script>
diff --git a/third_party/blink/web_tests/fast/forms/implicit-submission-expected.txt b/third_party/blink/web_tests/fast/forms/implicit-submission-expected.txt index 63e9015..42243de 100644 --- a/third_party/blink/web_tests/fast/forms/implicit-submission-expected.txt +++ b/third_party/blink/web_tests/fast/forms/implicit-submission-expected.txt
@@ -19,7 +19,7 @@ Single checkbox with a submit should submit: PASS Single checkbox with a submit disabled should not submit: PASS Single select should not submit: PASS -Select with a submit should submit: FAIL +Select with a submit should submit: PASS Select with a disabled submit should not submit: PASS Multi-line select with a submit should submit: PASS Multi-line select with a disabled submit should not submit: PASS
diff --git a/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index b2d6b886..62283c3 100644 --- a/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -12,7 +12,7 @@ Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +PASS internals.isSelectPopupVisible(popup) is false Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard.html b/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard.html index 4ac6b19..827a731 100644 --- a/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard.html +++ b/third_party/blink/web_tests/fast/forms/select/menulist-popup-open-hide-using-keyboard.html
@@ -52,7 +52,7 @@ debug('Test opening of popup using enter key'); popup.focus(); eventSender.keyDown('\r', []); - shouldBeTrue('internals.isSelectPopupVisible(popup)'); + shouldBeFalse('internals.isSelectPopupVisible(popup)'); popup.blur(); debug('Works for all platforms');
diff --git a/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html b/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html index 5893605..90aca3b 100644 --- a/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html +++ b/third_party/blink/web_tests/http/tests/forms/resources/date-picker-keyboard-cross-domain-iframe.html
@@ -7,9 +7,9 @@ input_date.focus(); if (internals.isFormControlsRefreshEnabled) { - eventSender.keyDown("Enter"); + eventSender.keyDown(" "); } else { - // Old picker needs Alt+Enter + // Old picker needs Alt+ArrowDown eventSender.keyDown("ArrowDown", ["altKey"]); }
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/fuchsia/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% rename from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt rename to third_party/blink/web_tests/platform/fuchsia/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/fuchsia/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt new file mode 100644 index 0000000..63e9015 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt
@@ -0,0 +1,30 @@ +Tests various combinations of form elements and how implicit submission works with them. + +Single text input should submit: PASS +Single text input with submit disabled should not submit: PASS +Multiple text inputs should not submit: PASS +Multiple text inputs with submit should submit: PASS +Multiple text inputs with submit disabled should not submit: PASS +Multiple text inputs and multiple submits, first submit disabled should not submit: PASS +Text input and text area, text input focused should submit: PASS +Text input and text area and a submit, text input focused should submit: PASS +Text input and text area and a disabled submit, text input focused should not submit: PASS +Text input and checkbox, text input focused should submit: PASS +Text input and radio, text input focused should submit: PASS +Text input and text area, textarea focused should not submit: PASS +Text input and checkbox, checkbox focused should not submit: PASS +Text input and radio, radio focused should not submit: PASS +Single radio should not submit: PASS +Single checkbox should not submit: PASS +Single checkbox with a submit should submit: PASS +Single checkbox with a submit disabled should not submit: PASS +Single select should not submit: PASS +Select with a submit should submit: FAIL +Select with a disabled submit should not submit: PASS +Multi-line select with a submit should submit: PASS +Multi-line select with a disabled submit should not submit: PASS +Text field and single select, text focused should submit: PASS +Text field and single select, select focused should not submit: PASS +Multiple text inputs with a button should submit: PASS +Multiple text inputs with a disabled button should not submit: PASS +Multiple text inputs with a hidden submit should submit: PASS
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/linux/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/mac-mac10.11/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/mac-mac10.12/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac10.13/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/mac-mac10.14/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac10.14/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac-retina/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/mac-retina/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac-retina/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1f4743f4..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,20 +5,20 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 -FAIL internals.isSelectPopupVisible(popup) should be true. Was false. +PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -FAIL internals.isSelectPopupVisible(popup) should be true. Was false. +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true Works for only mac Test opening of popup using up key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be true. Was false. PASS successfullyParsed is true TEST COMPLETE
diff --git a/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt new file mode 100644 index 0000000..63e9015 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt
@@ -0,0 +1,30 @@ +Tests various combinations of form elements and how implicit submission works with them. + +Single text input should submit: PASS +Single text input with submit disabled should not submit: PASS +Multiple text inputs should not submit: PASS +Multiple text inputs with submit should submit: PASS +Multiple text inputs with submit disabled should not submit: PASS +Multiple text inputs and multiple submits, first submit disabled should not submit: PASS +Text input and text area, text input focused should submit: PASS +Text input and text area and a submit, text input focused should submit: PASS +Text input and text area and a disabled submit, text input focused should not submit: PASS +Text input and checkbox, text input focused should submit: PASS +Text input and radio, text input focused should submit: PASS +Text input and text area, textarea focused should not submit: PASS +Text input and checkbox, checkbox focused should not submit: PASS +Text input and radio, radio focused should not submit: PASS +Single radio should not submit: PASS +Single checkbox should not submit: PASS +Single checkbox with a submit should submit: PASS +Single checkbox with a submit disabled should not submit: PASS +Single select should not submit: PASS +Select with a submit should submit: FAIL +Select with a disabled submit should not submit: PASS +Multi-line select with a submit should submit: PASS +Multi-line select with a disabled submit should not submit: PASS +Text field and single select, text focused should submit: PASS +Text field and single select, select focused should not submit: PASS +Multiple text inputs with a button should submit: PASS +Multiple text inputs with a disabled button should not submit: PASS +Multiple text inputs with a hidden submit should submit: PASS
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/platform/win7/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt new file mode 100644 index 0000000..63e9015 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/virtual/form-controls-refresh-disabled/fast/forms/implicit-submission-expected.txt
@@ -0,0 +1,30 @@ +Tests various combinations of form elements and how implicit submission works with them. + +Single text input should submit: PASS +Single text input with submit disabled should not submit: PASS +Multiple text inputs should not submit: PASS +Multiple text inputs with submit should submit: PASS +Multiple text inputs with submit disabled should not submit: PASS +Multiple text inputs and multiple submits, first submit disabled should not submit: PASS +Text input and text area, text input focused should submit: PASS +Text input and text area and a submit, text input focused should submit: PASS +Text input and text area and a disabled submit, text input focused should not submit: PASS +Text input and checkbox, text input focused should submit: PASS +Text input and radio, text input focused should submit: PASS +Text input and text area, textarea focused should not submit: PASS +Text input and checkbox, checkbox focused should not submit: PASS +Text input and radio, radio focused should not submit: PASS +Single radio should not submit: PASS +Single checkbox should not submit: PASS +Single checkbox with a submit should submit: PASS +Single checkbox with a submit disabled should not submit: PASS +Single select should not submit: PASS +Select with a submit should submit: FAIL +Select with a disabled submit should not submit: PASS +Multi-line select with a submit should submit: PASS +Multi-line select with a disabled submit should not submit: PASS +Text field and single select, text focused should submit: PASS +Text field and single select, select focused should not submit: PASS +Multiple text inputs with a button should submit: PASS +Multiple text inputs with a disabled button should not submit: PASS +Multiple text inputs with a hidden submit should submit: PASS
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt b/third_party/blink/web_tests/platform/win7/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt similarity index 87% copy from third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt copy to third_party/blink/web_tests/platform/win7/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt index 1020ae81..58f23520 100644 --- a/third_party/blink/web_tests/platform/mac/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt +++ b/third_party/blink/web_tests/platform/win7/virtual/form-controls-refresh-disabled/fast/forms/select/menulist-popup-open-hide-using-keyboard-expected.txt
@@ -5,14 +5,14 @@ These tests run specfically for Linux and Windows Test opening and closing of popup using alt and down arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening and closing of popup using alt and up arrow key PASS internals.isSelectPopupVisible(popup) is true -FAIL internals.isSelectPopupVisible(popup) should be false. Was true. +PASS internals.isSelectPopupVisible(popup) is false Test opening of popup using F4 PASS internals.isSelectPopupVisible(popup) is true Test opening of popup using enter key -PASS internals.isSelectPopupVisible(popup) is true +FAIL internals.isSelectPopupVisible(popup) should be false. Was true. Works for all platforms Test opening of popup using space key PASS internals.isSelectPopupVisible(popup) is true
diff --git a/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-open-with-enter-key.html b/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-with-enter-key.html similarity index 75% rename from third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-open-with-enter-key.html rename to third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-with-enter-key.html index 3207751..adfbb2e 100644 --- a/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-open-with-enter-key.html +++ b/third_party/blink/web_tests/virtual/controls-refresh/calendar-picker/date-picker-with-enter-key.html
@@ -13,8 +13,8 @@ test(() => { document.getElementById('date').focus(); eventSender.keyDown("Enter"); - assert_not_equals(internals.pagePopupWindow, null); -}, "Test opening date picker with Enter key."); + assert_equals(internals.pagePopupWindow, null); +}, "The date picker should not open with the Enter key."); </script> </body>
diff --git a/third_party/blink/web_tests/virtual/css-scroll-timeline/README.md b/third_party/blink/web_tests/virtual/css-scroll-timeline/README.md new file mode 100644 index 0000000..9211d1c --- /dev/null +++ b/third_party/blink/web_tests/virtual/css-scroll-timeline/README.md
@@ -0,0 +1,4 @@ +Virtual test suite for feature CSSScrollTimeline, which enables support for the @scroll-timeline rule and the animation-timeline property. + +https://drafts.csswg.org/scroll-animations-1/#animation-timeline +https://drafts.csswg.org/scroll-animations-1/#scroll-timeline-at-rule
diff --git a/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-computed-expected.txt b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-computed-expected.txt new file mode 100644 index 0000000..605af59 --- /dev/null +++ b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-computed-expected.txt
@@ -0,0 +1,25 @@ +This is a testharness.js-based test. +PASS Property animation-timeline value 'initial' +PASS Property animation-timeline value 'inherit' +PASS Property animation-timeline value 'unset' +PASS Property animation-timeline value 'revert' +PASS Property animation-timeline value 'auto' +PASS Property animation-timeline value 'none' +PASS Property animation-timeline value 'auto, auto' +PASS Property animation-timeline value 'none, none' +PASS Property animation-timeline value 'auto, none' +PASS Property animation-timeline value 'none, auto' +PASS Property animation-timeline value '"test"' +PASS Property animation-timeline value '"none"' +PASS Property animation-timeline value '"auto"' +PASS Property animation-timeline value '"initial"' +PASS Property animation-timeline value '"inherit"' +PASS Property animation-timeline value '"unset"' +PASS Property animation-timeline value '"revert"' +PASS Property animation-timeline value 'test' +PASS Property animation-timeline value 'test1, test2' +PASS Property animation-timeline value 'test1, "test2", none, test3, auto' +PASS The animation-timeline property shows up in CSSStyleDeclaration enumeration +PASS The animation-timeline property shows up in CSSStyleDeclaration.cssText +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt new file mode 100644 index 0000000..33d3cad --- /dev/null +++ b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-in-keyframe-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +PASS The animation-timeline property may not be used in keyframes +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-parsing-expected.txt b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-parsing-expected.txt new file mode 100644 index 0000000..8069434 --- /dev/null +++ b/third_party/blink/web_tests/virtual/css-scroll-timeline/external/wpt/scroll-animations/css/animation-timeline-parsing-expected.txt
@@ -0,0 +1,30 @@ +This is a testharness.js-based test. +PASS e.style['animation-timeline'] = "initial" should set the property value +PASS e.style['animation-timeline'] = "inherit" should set the property value +PASS e.style['animation-timeline'] = "unset" should set the property value +PASS e.style['animation-timeline'] = "revert" should set the property value +PASS e.style['animation-timeline'] = "auto" should set the property value +PASS e.style['animation-timeline'] = "none" should set the property value +PASS e.style['animation-timeline'] = "auto, auto" should set the property value +PASS e.style['animation-timeline'] = "none, none" should set the property value +PASS e.style['animation-timeline'] = "auto, none" should set the property value +PASS e.style['animation-timeline'] = "none, auto" should set the property value +PASS e.style['animation-timeline'] = "\"test\"" should set the property value +PASS e.style['animation-timeline'] = "\"none\"" should set the property value +PASS e.style['animation-timeline'] = "\"auto\"" should set the property value +PASS e.style['animation-timeline'] = "\"initial\"" should set the property value +PASS e.style['animation-timeline'] = "\"inherit\"" should set the property value +PASS e.style['animation-timeline'] = "\"unset\"" should set the property value +PASS e.style['animation-timeline'] = "\"revert\"" should set the property value +PASS e.style['animation-timeline'] = "test" should set the property value +PASS e.style['animation-timeline'] = "test1, test2" should set the property value +PASS e.style['animation-timeline'] = "test1, \"test2\", none, test3, auto" should set the property value +PASS e.style['animation-timeline'] = "10px" should not set the property value +PASS e.style['animation-timeline'] = "auto auto" should not set the property value +PASS e.style['animation-timeline'] = "none none" should not set the property value +PASS e.style['animation-timeline'] = "foo bar" should not set the property value +PASS e.style['animation-timeline'] = "\"foo\" \"bar\"" should not set the property value +PASS e.style['animation-timeline'] = "rgb(1, 2, 3)" should not set the property value +PASS e.style['animation-timeline'] = "#fefefe" should not set the property value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-blob.html similarity index 78% rename from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html rename to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-blob.html index adac4ae..5c792ca0 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-blob.html
@@ -2,4 +2,4 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/window-tests-blob.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-enumeration.html similarity index 76% copy from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html copy to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-enumeration.html index adac4ae..52a4317 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-enumeration.html
@@ -2,4 +2,4 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/window-tests-enumeration.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-getTables-large-fonts.html similarity index 73% copy from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html copy to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-getTables-large-fonts.html index adac4ae..2e9b1ad 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-getTables-large-fonts.html
@@ -2,4 +2,4 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/window-tests-getTables-large-fonts.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-getTables.html similarity index 77% copy from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html copy to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-getTables.html index adac4ae..b937adcf 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window-getTables.html
@@ -2,4 +2,4 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/window-tests-getTables.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window.html deleted file mode 100644 index 9f2008f..0000000 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-window.html +++ /dev/null
@@ -1,5 +0,0 @@ -<!DOCTYPE html> -<script src="../../../../../resources/testharness.js"></script> -<script src="../../../../../resources/testharnessreport.js"></script> -<script src="resources/test-expectations.js"></script> -<script src="resources/window-tests.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-blob.html similarity index 66% copy from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html copy to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-blob.html index adac4ae..f8aa4d0 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-blob.html
@@ -2,4 +2,5 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/worker-utils.js"></script> +<script src="resources/worker-tests-blob.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-enumeration.html similarity index 64% copy from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html copy to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-enumeration.html index adac4ae..ec4ce74 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-enumeration.html
@@ -2,4 +2,5 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/worker-utils.js"></script> +<script src="resources/worker-tests-enumeration.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-getTables.html similarity index 64% copy from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html copy to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-getTables.html index adac4ae..2ffa4f9 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers.html +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/font-access-workers-getTables.html
@@ -2,4 +2,5 @@ <script src="../../../../../resources/testharness.js"></script> <script src="../../../../../resources/testharnessreport.js"></script> <script src="resources/test-expectations.js"></script> -<script src="resources/worker-tests.js"></script> +<script src="resources/worker-utils.js"></script> +<script src="resources/worker-tests-getTables.js"></script>
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/test-expectations.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/test-expectations.js index 38f0c6c0..01ed170 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/test-expectations.js +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/test-expectations.js
@@ -1,10 +1,20 @@ 'use strict'; +const TEST_SIZE_CATEGORY = { + // Fonts with file smaller than 1MiB. + small: 'small', + // Fonts with file between 1 and 20MiB. + medium: 'medium', + // Fonts with file larger than 20MiB. + large: 'large', +}; + const MAC_FONTS = [ { postscriptName: 'Monaco', fullName: 'Monaco', family: 'Monaco', + label: TEST_SIZE_CATEGORY.small, expectedTables: [ // Tables related to TrueType. 'cvt ', 'glyf', 'loca', 'prep', 'gasp', @@ -14,6 +24,7 @@ postscriptName: 'Menlo-Regular', fullName: 'Menlo Regular', family: 'Menlo', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -22,6 +33,7 @@ postscriptName: 'Menlo-Bold', fullName: 'Menlo Bold', family: 'Menlo', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -30,6 +42,7 @@ postscriptName: 'Menlo-BoldItalic', fullName: 'Menlo Bold Italic', family: 'Menlo', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -39,6 +52,7 @@ postscriptName: 'GujaratiMT', fullName: 'Gujarati MT', family: 'Gujarati MT', + label: TEST_SIZE_CATEGORY.small, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -47,6 +61,7 @@ postscriptName: 'GujaratiMT-Bold', fullName: 'Gujarati MT Bold', family: 'Gujarati MT', + label: TEST_SIZE_CATEGORY.small, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -55,6 +70,7 @@ postscriptName: 'DevanagariMT', fullName: 'Devanagari MT', family: 'Devanagari MT', + label: TEST_SIZE_CATEGORY.small, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -63,6 +79,7 @@ postscriptName: 'DevanagariMT-Bold', fullName: 'Devanagari MT Bold', family: 'Devanagari MT', + label: TEST_SIZE_CATEGORY.small, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -72,6 +89,7 @@ postscriptName: 'HiraMinProN-W3', fullName: 'Hiragino Mincho ProN W3', family: 'Hiragino Mincho ProN', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'CFF ', 'VORG', ], @@ -80,6 +98,7 @@ postscriptName: 'HiraMinProN-W6', fullName: 'Hiragino Mincho ProN W6', family: 'Hiragino Mincho ProN', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'CFF ', 'VORG', ], @@ -89,6 +108,7 @@ postscriptName: 'AppleGothic', fullName: 'AppleGothic Regular', family: 'AppleGothic', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'cvt ', 'glyf', 'loca', ], @@ -97,6 +117,7 @@ postscriptName: 'AppleMyungjo', fullName: 'AppleMyungjo Regular', family: 'AppleMyungjo', + label: TEST_SIZE_CATEGORY.medium, expectedTables: [ 'cvt ', 'glyf', 'loca', ], @@ -106,6 +127,7 @@ postscriptName: 'STHeitiTC-Light', fullName: 'Heiti TC Light', family: 'Heiti TC', + label: TEST_SIZE_CATEGORY.large, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -114,6 +136,7 @@ postscriptName: 'STHeitiTC-Medium', fullName: 'Heiti TC Medium', family: 'Heiti TC', + label: TEST_SIZE_CATEGORY.large, expectedTables: [ 'cvt ', 'glyf', 'loca', 'prep', ], @@ -123,6 +146,7 @@ postscriptName: 'AppleColorEmoji', fullName: 'Apple Color Emoji', family: 'Apple Color Emoji', + label: TEST_SIZE_CATEGORY.large, expectedTables: [ 'glyf', 'loca', // Tables related to Bitmap Glyphs. @@ -145,7 +169,11 @@ 'post', ]; -function getExpectedFontSet() { +function getEnumerationTestSet(options) { + options = Object.assign({ + labelFilter: [], + }, options); + // Verify (by font family) that some standard fonts have been returned. let platform; if (navigator.platform.indexOf("Win") !== -1) { @@ -159,11 +187,18 @@ } assert_not_equals(platform, 'generic', 'Platform must be detected.'); + + let output = []; if (platform === 'mac') { - return MAC_FONTS; + output = MAC_FONTS; } - return []; + if (options.labelFilter.length && output.length) { + const labelFilter = new Set(options.labelFilter); + output = output.filter(f => labelFilter.has(f.label)); + } + + return output; } function getMoreExpectedTables(expectations) { @@ -176,8 +211,7 @@ return output; } -async function filterFontSet(iterator, expectedFonts) { - +async function filterEnumeration(iterator, expectedFonts) { const nameSet = new Set(); for (const e of expectedFonts) { nameSet.add(e.postscriptName); @@ -237,3 +271,73 @@ const items = Array.from(set); return JSON.stringify(items); } + +async function parseFontData(fontBlob) { + const fontInfo = { + errors: [], + numTables: 0, + }; + const versionTag = await getTag(fontBlob, 0); + + fontInfo.version = sfntVersionInfo(versionTag); + if (fontInfo.version === 'UNKNOWN') { + fontInfo.errors.push(`versionTag: "${versionTag}"`); + } + + const numTables = await getUint16(fontBlob, 4); + [fontInfo.tables, fontInfo.tableMeta] = await getTableData(fontBlob, numTables); + + return fontInfo; +} + +async function getTableData(fontBlob, numTables) { + const dataMap = new Map(); + const metaMap = new Map(); + let blobOffset = 12; + + for (let i = 0; i < numTables; i++) { + const tag = await getTag(fontBlob, blobOffset); + const checksum = await getUint32(fontBlob, blobOffset + 4); + const offset = await getUint32(fontBlob, blobOffset + 8); + const size = await getUint32(fontBlob, blobOffset + 12); + const tableBlob = fontBlob.slice(offset, offset + size); + dataMap.set(tag, tableBlob); + metaMap.set(tag, {checksum, offset, size}); + blobOffset += 16; + } + + return [dataMap, metaMap]; +} + +function sfntVersionInfo(version) { + // Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font + switch (version) { + case '\x00\x01\x00\x00': + case 'true': + case 'typ1': + return 'truetype'; + case 'OTTO': + return 'cff'; + default: + return 'UNKNOWN'; + } +} + +async function getTag(blob, offset) { + return (new TextDecoder).decode( + await blob.slice(offset, offset + 4).arrayBuffer()); +} + +async function getUint16(blob, offset) { + const slice = blob.slice(offset, offset + 2); + const buf = await slice.arrayBuffer(); + const dataView = new DataView(buf); + return dataView.getUint16(0); +} + +async function getUint32(blob, offset) { + const slice = blob.slice(offset, offset + 4); + const buf = await slice.arrayBuffer(); + const dataView = new DataView(buf); + return dataView.getUint32(0); +}
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-blob.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-blob.js new file mode 100644 index 0000000..0183232f --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-blob.js
@@ -0,0 +1,29 @@ +'use strict'; + +promise_test(async t => { + const iterator = navigator.fonts.query(); + const expectedFonts = await filterEnumeration(iterator, + getEnumerationTestSet({ + labelFilter: [TEST_SIZE_CATEGORY.small]})); + const additionalExpectedTables = getMoreExpectedTables(expectedFonts); + + for (const f of expectedFonts) { + const data = await f.blob(); + assert_not_equals(data.size, 0, 'Returned Blob size slot is populated.'); + const buf = await data.arrayBuffer(); + assert_not_equals(buf.length, 0, 'Returned ArrayBuffer is not empty.'); + assert_equals(data.type, 'application/octet-stream', 'Returned Blob is of type octet-stream.'); + + const parsedData = await parseFontData(data); + assert_not_equals(parsedData.version, 'UNKNOWN', 'SFNT version is a known type.'); + + assert_not_equals(parsedData.tables.size, 0, "Should not have tables of size zero."); + assert_font_has_tables(f.postscriptName, parsedData.tables, BASE_TABLES); + + if (f.postscriptName in additionalExpectedTables) { + assert_font_has_tables(f.postscriptName, + parsedData.tables, + additionalExpectedTables[f.postscriptName]); + } + } +}, 'blob(): fonts have expected tables that are not empty');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-enumeration.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-enumeration.js new file mode 100644 index 0000000..7365430 --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-enumeration.js
@@ -0,0 +1,15 @@ +'use strict'; + +promise_test(async t => { + const iterator = navigator.fonts.query(); + assert_equals(typeof iterator, 'object', 'query() should return an Object'); + assert_true(!!iterator[Symbol.asyncIterator], + 'query() has an asyncIterator method'); + + const availableFonts = []; + for await (const f of iterator) { + availableFonts.push(f); + } + + assert_fonts_exist(availableFonts, getEnumerationTestSet()); +}, 'query(): standard fonts returned');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-getTables-large-fonts.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-getTables-large-fonts.js new file mode 100644 index 0000000..a4c11df --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-getTables-large-fonts.js
@@ -0,0 +1,18 @@ +'use strict'; + +promise_test(async t => { + const iterator = navigator.fonts.query(); + + const expectations = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.large]}); + const expectedFonts = await filterEnumeration(iterator, expectations); + const additionalExpectedTables = getMoreExpectedTables(expectations); + for (const f of expectedFonts) { + const tables = await f.getTables(); + assert_font_has_tables(f.postscriptName, tables, BASE_TABLES); + if (f.postscriptName in additionalExpectedTables) { + assert_font_has_tables(f.postscriptName, + tables, + additionalExpectedTables[f.postscriptName]); + } + } +}, 'getTables(): large fonts have expected non-empty tables');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-getTables.js similarity index 65% rename from third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests.js rename to third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-getTables.js index f3bf2bca..88026a01 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests.js +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/window-tests-getTables.js
@@ -1,27 +1,10 @@ 'use strict'; promise_test(async t => { - const iterator = navigator.fonts.query(); - assert_true(iterator instanceof Object, - 'query() should return an Object'); - assert_true(!!iterator[Symbol.asyncIterator], - 'query() has an asyncIterator method'); - - const availableFonts = []; - for await (const f of iterator) { - availableFonts.push(f); - } - - assert_fonts_exist(availableFonts, getExpectedFontSet()); -}, 'query(): standard fonts returned'); - -promise_test(async t => { const iterator = navigator.fonts.query(); - assert_true(iterator instanceof Object, - 'query() should return an Object'); - const expectations = getExpectedFontSet(); - const expectedFonts = await filterFontSet(iterator, expectations); + const expectations = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + const expectedFonts = await filterEnumeration(iterator, expectations); const additionalExpectedTables = getMoreExpectedTables(expectations); for (const f of expectedFonts) { const tables = await f.getTables(); @@ -32,14 +15,31 @@ additionalExpectedTables[f.postscriptName]); } } -}, 'getTables(): all fonts have expected tables that are not empty'); +}, 'getTables(): small sized fonts have expected non-empty tables'); promise_test(async t => { const iterator = navigator.fonts.query(); - assert_true(iterator instanceof Object, - 'query() should return an Object'); - const expectedFonts = await filterFontSet(iterator, getExpectedFontSet()); + const expectations = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.medium]}); + const expectedFonts = await filterEnumeration(iterator, expectations); + const additionalExpectedTables = getMoreExpectedTables(expectations); + for (const f of expectedFonts) { + const tables = await f.getTables(); + assert_font_has_tables(f.postscriptName, tables, BASE_TABLES); + if (f.postscriptName in additionalExpectedTables) { + assert_font_has_tables(f.postscriptName, + tables, + additionalExpectedTables[f.postscriptName]); + } + } +}, 'getTables(): medium sized fonts have expected non-empty tables'); + +promise_test(async t => { + const iterator = navigator.fonts.query(); + + const expectedFonts = await filterEnumeration(iterator, + getEnumerationTestSet({ + labelFilter: [TEST_SIZE_CATEGORY.small]})); const inputs = [ ['cmap'], // Single item. ['cmap', 'head'], // Multiple items. @@ -59,10 +59,10 @@ promise_test(async t => { const iterator = navigator.fonts.query(); - assert_true(iterator instanceof Object, - 'query() should return an Object'); - const expectedFonts = await filterFontSet(iterator, getExpectedFontSet()); + const expectedFonts = await filterEnumeration(iterator, + getEnumerationTestSet({ + labelFilter: [TEST_SIZE_CATEGORY.small]})); const inputs = [ // Nonexistent Tag. ['ABCD'], @@ -81,10 +81,10 @@ promise_test(async t => { const iterator = navigator.fonts.query(); - assert_true(iterator instanceof Object, - 'query() should return an Object'); - const expectedFonts = await filterFontSet(iterator, getExpectedFontSet()); + const expectedFonts = await filterEnumeration(iterator, + getEnumerationTestSet({ + labelFilter: [TEST_SIZE_CATEGORY.small]})); const inputs = [ // empty string [''], @@ -120,10 +120,10 @@ promise_test(async t => { const iterator = navigator.fonts.query(); - assert_true(iterator instanceof Object, - 'query() should return an Object'); - const expectedFonts = await filterFontSet(iterator, getExpectedFontSet()); + const expectedFonts = await filterEnumeration(iterator, + getEnumerationTestSet({ + labelFilter: [TEST_SIZE_CATEGORY.small]})); const inputs = [ { // One exists, one doesn't.
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-font-access.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-font-access.js index b98c6f01..f0e3e7a7 100644 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-font-access.js +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-font-access.js
@@ -56,6 +56,37 @@ return output; } +async function blob(options) { + options = Object.assign({ + postscriptNameFilter: [], + }, options); + + const nameFilterSet = new Set(options.postscriptNameFilter); + const iterator = navigator.fonts.query(); + const localFonts = []; + for await (const f of navigator.fonts.query()) { + if (nameFilterSet.size > 0) { + if (!nameFilterSet.has(f.postscriptName)) { + continue; + } + } + localFonts.push(f); + } + + let output = []; + for (const f of localFonts) { + const tableBlob = await f.blob(); + output.push({ + postscriptName: f.postscriptName, + fullName: f.fullName, + family: f.family, + blob: tableBlob, + }); + } + + return output; +} + async function handleMessage(event) { try { switch(event.data.action) { @@ -68,6 +99,9 @@ case "getTables": postMessage({type: "getTables", data: await getTables(event.data.options)}); break; + case "blob": + postMessage({type: "blob", data: await blob(event.data.options)}); + break; default: postMessage({type: "error", data: "FAILURE: Received unknown message: " + event.data}); }
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-blob.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-blob.js new file mode 100644 index 0000000..901c05f --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-blob.js
@@ -0,0 +1,49 @@ +'use strict'; + +promise_test(async t => { + const worker = new Worker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + const expectedFonts = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + + const promise = promiseHandleMessage(t, worker); + worker.postMessage({ + action: 'blob', + options: { + postscriptNameFilter: expectedFonts.map(f => f.postscriptName), + } + }); + const event = await promise; + + assert_equals(event.data.type, 'blob', 'Response is of type blob.'); + + const localFonts = event.data.data; + assert_fonts_exist(localFonts, expectedFonts); + for (const f of localFonts) { + const parsedData = await parseFontData(f.blob); + assert_font_has_tables(f.postscriptName, parsedData.tables, BASE_TABLES); + } +}, 'DedicatedWorker, blob(): all fonts have base tables that are not empty'); + +promise_test(async t => { + const worker = new SharedWorker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + const expectedFonts = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + + const promise = promiseHandleMessage(t, worker); + worker.port.postMessage({ + action: 'blob', + options: { + postscriptNameFilter: expectedFonts.map(f => f.postscriptName), + } + }); + const event = await promise; + + assert_equals(event.data.type, 'blob', 'Response is of type blob.'); + + const localFonts = event.data.data; + assert_fonts_exist(localFonts, expectedFonts); + for (const f of localFonts) { + const parsedData = await parseFontData(f.blob); + assert_font_has_tables(f.postscriptName, parsedData.tables, BASE_TABLES); + } +}, 'SharedWorker, blob(): all fonts have base tables that are not empty');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-enumeration.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-enumeration.js new file mode 100644 index 0000000..af11e09 --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-enumeration.js
@@ -0,0 +1,33 @@ +'use strict'; + +promise_test(async t => { + const worker = new Worker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + + const promise = promiseHandleMessage(t, worker); + worker.postMessage({action: 'query'}); + const event = await promise; + + assert_equals(event.data.type, 'query', "Response is of type query."); + + const localFonts = event.data.data; + assert_true(Array.isArray(localFonts), + `Response is of type Array. Instead got: ${localFonts}.`); + assert_fonts_exist(localFonts, getEnumerationTestSet()); +}, 'DedicatedWorker, query(): returns fonts'); + +promise_test(async t => { + const worker = new SharedWorker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + + const promise = promiseHandleMessage(t, worker); + worker.port.postMessage({action: 'query'}); + const event = await promise; + + assert_equals(event.data.type, 'query', 'Response is of type query.'); + + const localFonts = event.data.data; + assert_true(Array.isArray(localFonts), + `Response is of type Array. Instead got: ${localFonts}.`); + assert_fonts_exist(localFonts, getEnumerationTestSet()); +}, 'SharedWorker, query(): returns fonts');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-getTables.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-getTables.js new file mode 100644 index 0000000..39af27a --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests-getTables.js
@@ -0,0 +1,103 @@ +'use strict'; + +promise_test(async t => { + const worker = new Worker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + const expectedFonts = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + + const promise = promiseHandleMessage(t, worker); + worker.postMessage({ + action: 'getTables', + options: { + postscriptNameFilter: expectedFonts.map(f => f.postscriptName), + } + }); + const event = await promise; + + assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); + + const localFonts = event.data.data; + assert_fonts_exist(localFonts, expectedFonts); + for (const f of localFonts) { + assert_font_has_tables(f.postscriptName, f.tables, BASE_TABLES); + } +}, 'DedicatedWorker, getTables(): all fonts have base tables that are not empty'); + +promise_test(async t => { + const worker = new Worker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + const expectedFonts = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + + const promise = promiseHandleMessage(t, worker); + + const tableQuery = ["cmap", "head"]; + worker.postMessage({ + action: 'getTables', + options: { + postscriptNameFilter: expectedFonts.map(f => f.postscriptName), + tables: tableQuery, + } + }); + + const event = await promise; + + assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); + + const localFonts = event.data.data; + assert_fonts_exist(localFonts, expectedFonts); + for (const f of localFonts) { + assert_font_has_tables(f.postscriptName, f.tables, tableQuery); + } +}, 'DedicatedWorker, getTables([tableName,...]): returns tables'); + +promise_test(async t => { + const worker = new SharedWorker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + const expectedFonts = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + + const promise = promiseHandleMessage(t, worker); + + worker.port.postMessage({ + action: 'getTables', + options: { + postscriptNameFilter: expectedFonts.map(f => f.postscriptName), + } + }); + + const event = await promise; + + assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); + + const localFonts = event.data.data; + assert_fonts_exist(localFonts, expectedFonts); + for (const f of localFonts) { + assert_font_has_tables(f.postscriptName, f.tables, BASE_TABLES); + } +}, 'SharedWorker, getTables(): all fonts have base tables that are not empty'); + +promise_test(async t => { + const worker = new SharedWorker('resources/worker-font-access.js'); + await promiseWorkerReady(t, worker); + const expectedFonts = getEnumerationTestSet({labelFilter: [TEST_SIZE_CATEGORY.small]}); + + const promise = promiseHandleMessage(t, worker); + + const tableQuery = ["cmap", "head"]; + worker.port.postMessage({ + action: 'getTables', + options: { + postscriptNameFilter: expectedFonts.map(f => f.postscriptName), + tables: tableQuery, + } + }); + + const event = await promise; + + assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); + + const localFonts = event.data.data; + assert_fonts_exist(localFonts, expectedFonts); + for (const f of localFonts) { + assert_font_has_tables(f.postscriptName, f.tables, tableQuery); + } +}, 'SharedWorker, getTables([tableName,...]): returns tables that are not empty');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests.js deleted file mode 100644 index c30e77fa..0000000 --- a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-tests.js +++ /dev/null
@@ -1,183 +0,0 @@ -'use strict'; - -function promiseWorkerReady(t, worker) { - return new Promise((resolve, reject) => { - let timeout; - - const readyFunc = t.step_func(event => { - if (event.data.type != 'ready') { - reject(event); - } - window.clearTimeout(timeout); - resolve(); - }); - - // Setting a timeout because the the worker - // may not be ready to listen to the postMessage. - timeout = t.step_timeout(() => { - if ('port' in worker) { - if (!worker.port.onmessage) { - worker.port.onmessage = readyFunc; - } - worker.port.postMessage({action: 'ping'}); - } else { - if (!worker.onmessage) { - worker.onmessage = readyFunc; - } - worker.postMessage({action: 'ping'}); - } - }, 10); - }); -} - -function promiseHandleMessage(t, worker) { - return new Promise((resolve, reject) => { - const handler = t.step_func(event => { - if (event.data.type === 'ready') { - // Ignore: may received duplicate readiness messages. - return; - } - - if (event.data.type === 'error') { - reject(event); - } - - resolve(event); - }); - - if ('port' in worker) { - worker.port.onmessage = handler; - } else { - worker.onmessage = handler; - } - }); -} - -promise_test(async t => { - const worker = new Worker('resources/worker-font-access.js'); - await promiseWorkerReady(t, worker); - - const promise = promiseHandleMessage(t, worker); - worker.postMessage({action: 'query'}); - const event = await promise; - - assert_equals(event.data.type, 'query', "Response is of type query."); - - const localFonts = event.data.data; - assert_true(Array.isArray(localFonts), - `Response is of type Array. Instead got: ${localFonts}.`); -}, 'DedicatedWorker, query(): returns fonts'); - -promise_test(async t => { - const worker = new Worker('resources/worker-font-access.js'); - await promiseWorkerReady(t, worker); - - const promise = promiseHandleMessage(t, worker); - worker.postMessage({ - action: 'getTables', - options: { - postscriptNameFilter: getExpectedFontSet().map(f => f.postscriptName), - } - }); - const event = await promise; - - assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); - - const localFonts = event.data.data; - assert_fonts_exist(localFonts, getExpectedFontSet()); - for (const f of localFonts) { - assert_font_has_tables(f.postscriptName, f.tables, BASE_TABLES); - } -}, 'DedicatedWorker, getTables(): all fonts have base tables that are not empty'); - -promise_test(async t => { - const worker = new Worker('resources/worker-font-access.js'); - await promiseWorkerReady(t, worker); - - const promise = promiseHandleMessage(t, worker); - - const tableQuery = ["cmap", "head"]; - worker.postMessage({ - action: 'getTables', - options: { - postscriptNameFilter: getExpectedFontSet().map(f => f.postscriptName), - tables: tableQuery, - } - }); - - const event = await promise; - - assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); - - const localFonts = event.data.data; - assert_fonts_exist(localFonts, getExpectedFontSet()); - for (const f of localFonts) { - assert_font_has_tables(f.postscriptName, f.tables, tableQuery); - } -}, 'DedicatedWorker, getTables([tableName,...]): returns tables'); - -promise_test(async t => { - const worker = new SharedWorker('resources/worker-font-access.js'); - await promiseWorkerReady(t, worker); - - const promise = promiseHandleMessage(t, worker); - worker.port.postMessage({action: 'query'}); - const event = await promise; - - assert_equals(event.data.type, 'query', 'Response is of type query.'); - - const localFonts = event.data.data; - assert_true(Array.isArray(localFonts), - `Response is of type Array. Instead got: ${localFonts}.`); - assert_fonts_exist(localFonts, getExpectedFontSet()); -}, 'SharedWorker, query(): returns fonts'); - -promise_test(async t => { - const worker = new SharedWorker('resources/worker-font-access.js'); - await promiseWorkerReady(t, worker); - - const promise = promiseHandleMessage(t, worker); - - worker.port.postMessage({ - action: 'getTables', - options: { - postscriptNameFilter: getExpectedFontSet().map(f => f.postscriptName), - } - }); - - const event = await promise; - - assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); - - const localFonts = event.data.data; - assert_fonts_exist(localFonts, getExpectedFontSet()); - for (const f of localFonts) { - assert_font_has_tables(f.postscriptName, f.tables, BASE_TABLES); - } -}, 'SharedWorker, getTables(): all fonts have base tables that are not empty'); - -promise_test(async t => { - const worker = new SharedWorker('resources/worker-font-access.js'); - await promiseWorkerReady(t, worker); - - const promise = promiseHandleMessage(t, worker); - - const tableQuery = ["cmap", "head"]; - worker.port.postMessage({ - action: 'getTables', - options: { - postscriptNameFilter: getExpectedFontSet().map(f => f.postscriptName), - tables: tableQuery, - } - }); - - const event = await promise; - - assert_equals(event.data.type, 'getTables', 'Response is of type getTables.'); - - const localFonts = event.data.data; - assert_fonts_exist(localFonts, getExpectedFontSet()); - for (const f of localFonts) { - assert_font_has_tables(f.postscriptName, f.tables, tableQuery); - } -}, 'SharedWorker, getTables([tableName,...]): returns tables that are not empty');
diff --git a/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-utils.js b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-utils.js new file mode 100644 index 0000000..712d07305e2 --- /dev/null +++ b/third_party/blink/web_tests/virtual/font-access/http/tests/font-access/resources/worker-utils.js
@@ -0,0 +1,54 @@ +'use strict'; + +function promiseWorkerReady(t, worker) { + return new Promise((resolve, reject) => { + let timeout; + + const readyFunc = t.step_func(event => { + if (event.data.type != 'ready') { + reject(event); + } + window.clearTimeout(timeout); + resolve(); + }); + + // Setting a timeout because the the worker + // may not be ready to listen to the postMessage. + timeout = t.step_timeout(() => { + if ('port' in worker) { + if (!worker.port.onmessage) { + worker.port.onmessage = readyFunc; + } + worker.port.postMessage({action: 'ping'}); + } else { + if (!worker.onmessage) { + worker.onmessage = readyFunc; + } + worker.postMessage({action: 'ping'}); + } + }, 10); + }); +} + +function promiseHandleMessage(t, worker) { + return new Promise((resolve, reject) => { + const handler = t.step_func(event => { + if (event.data.type === 'ready') { + // Ignore: may received duplicate readiness messages. + return; + } + + if (event.data.type === 'error') { + reject(event); + } + + resolve(event); + }); + + if ('port' in worker) { + worker.port.onmessage = handler; + } else { + worker.onmessage = handler; + } + }); +}
diff --git a/third_party/blink/web_tests/virtual/lazyload-policy/external/wpt/feature-policy/experimental-features/lazyload/README.txt b/third_party/blink/web_tests/virtual/lazyload-policy/external/wpt/feature-policy/experimental-features/lazyload/README.txt deleted file mode 100644 index 639e356..0000000 --- a/third_party/blink/web_tests/virtual/lazyload-policy/external/wpt/feature-policy/experimental-features/lazyload/README.txt +++ /dev/null
@@ -1,2 +0,0 @@ -# This suite runs the tests in virtual/lazyload-policy/external/wpt/feature-policy/experimental-features/lazyload/ -# with --enable-blink-features=LazyFrameLoading.
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 8d03825..ed41288f 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -607,7 +607,6 @@ attribute MEDIA_RULE attribute NAMESPACE_RULE attribute PAGE_RULE - attribute PROPERTY_RULE attribute STYLE_RULE attribute SUPPORTS_RULE getter cssText
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt index 08da363..924bd5b1 100644 --- a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt +++ b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
@@ -34,8 +34,6 @@ gyroscope hid idle-detection -lazyload -loading-frame-default-eager magnetometer microphone midi
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index b37fe851..2f7560bc 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -807,7 +807,6 @@ attribute MEDIA_RULE attribute NAMESPACE_RULE attribute PAGE_RULE - attribute PROPERTY_RULE attribute STYLE_RULE attribute SUPPORTS_RULE getter cssText
diff --git a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp index 8c0c89e..9523fc5 100644 --- a/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp +++ b/tools/clang/rewrite_raw_ptr_fields/RewriteRawPtrFields.cpp
@@ -482,6 +482,13 @@ // Matches expressions that used to return a value of type |SomeClass*| // but after the rewrite return an instance of |CheckedPtr<SomeClass>|. + // Many such expressions might need additional changes after the rewrite: + // - Some expressions (printf args, const_cast args, etc.) might need |.get()| + // appended. + // - Using such expressions in specific contexts (e.g. as in-out arguments or + // as a return value of a function returning references) may require + // additional work and should cause related fields to be emitted as + // candidates for the --field-filter-file parameter. auto affected_member_expr_matcher = memberExpr(member(field_decl_matcher)).bind("affectedMemberExpr"); auto affected_implicit_expr_matcher = implicitCastExpr(has(expr(anyOf( @@ -491,19 +498,50 @@ // 2nd nested implicitCastExpr is present in case of: // |const auto* v = s.ptr_field;| expr(implicitCastExpr(has(affected_member_expr_matcher))))))); + auto affected_expr_matcher = + expr(anyOf(affected_member_expr_matcher, affected_implicit_expr_matcher)); - // Printf-style call expr ========= + // Places where |.get()| needs to be appended ========= // Given // void foo(const S& s) { // printf("%p", s.y); + // const_cast<...>(s.y) + // reinterpret_cast<...>(s.y) // } - // matches the |s.y| expr if it matches the |affected_implicit_expr_matcher| - // above. - auto affected_printf_arg_matcher = - expr(allOf(affected_implicit_expr_matcher, - hasParent(callExpr(callee(functionDecl(isVariadic())))))); - AffectedExprRewriter printf_arg_rewriter(&replacements_printer); - match_finder.addMatcher(affected_printf_arg_matcher, &printf_arg_rewriter); + // matches the |s.y| expr if it matches the |affected_expr_matcher| above. + auto affected_expr_that_needs_fixing_matcher = expr(allOf( + affected_expr_matcher, + hasParent(expr(anyOf(callExpr(callee(functionDecl(isVariadic()))), + cxxConstCastExpr(), cxxReinterpretCastExpr()))))); + AffectedExprRewriter affected_expr_rewriter(&replacements_printer); + match_finder.addMatcher(affected_expr_that_needs_fixing_matcher, + &affected_expr_rewriter); + + // Affected ternary operator args ========= + // Given + // void foo(const S& s) { + // cond ? s.y : ... + // } + // binds the |s.y| expr if it matches the |affected_expr_matcher| above. + auto affected_ternary_operator_arg_matcher = + conditionalOperator(eachOf(hasTrueExpression(affected_expr_matcher), + hasFalseExpression(affected_expr_matcher))); + match_finder.addMatcher(affected_ternary_operator_arg_matcher, + &affected_expr_rewriter); + + // |auto| type declarations ========= + // Given + // struct S { int* y; }; + // void foo(const S& s) { + // auto* p = s.y; + // } + // binds the |s.y| expr if it matches the |affected_expr_matcher| above. + auto auto_var_decl_matcher = declStmt(forEach(varDecl( + allOf(hasType(pointerType(pointee(autoType()))), + hasInitializer(anyOf( + affected_implicit_expr_matcher, + initListExpr(hasInit(0, affected_implicit_expr_matcher)))))))); + match_finder.addMatcher(auto_var_decl_matcher, &affected_expr_rewriter); // Prepare and run the tool. std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc index 1e77ecd..59393bc 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc +++ b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-expected.cc
@@ -2,15 +2,92 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <stdint.h> // for uintptr_t + #include "base/memory/checked_ptr.h" -class SomeClass; +class SomeClass {}; +class DerivedClass : public SomeClass {}; struct MyStruct { CheckedPtr<SomeClass> ptr; CheckedPtr<SomeClass> ptr2; + CheckedPtr<const SomeClass> const_ptr; + int (*func_ptr_field)(); }; +namespace auto_tests { + +MyStruct* GetMyStruct() { + return nullptr; +} + +SomeClass* GetSomeClass() { + return nullptr; +} + +SomeClass* ConvertSomeClassToSomeClass(SomeClass* some_class) { + return some_class; +} + +void foo() { + MyStruct my_struct; + + // After the rewrite |my_struct.ptr_field| is no longer a pointer, + // so |auto*| won't work. We fix this up, by appending |.get()|. + // Expected rewrite: auto* ptr_var = my_struct.ptr.get(); + auto* ptr_var = my_struct.ptr.get(); + + // Tests for other kinds of initialization. + // Expected rewrite: |.get()| should be appended in both cases below. + auto* init_test1(my_struct.ptr.get()); + auto* init_test2{my_struct.ptr.get()}; + + // Test for handling of the |const| qualifier. + // Expected rewrite: const auto* ptr_var = my_struct.ptr.get(); + const auto* const_ptr_var = my_struct.ptr.get(); + + // More complicated initialization expression, but the |ptr_field| struct + // member dereference is still the top/last expression here. + // Expected rewrite: ...->ptr.get() + auto* complicated_var = GetMyStruct()->ptr.get(); + + // The test below covers: + // 1. Two variables with single |auto|, + // 2. Tricky placement of |*| (next to the variable name). + // Expected rewrite: ...ptr.get()... (twice in the 2nd example). + auto *ptr_var1 = my_struct.ptr.get(), *ptr_var2 = GetSomeClass(); + auto *ptr_var3 = my_struct.ptr.get(), *ptr_var4 = my_struct.ptr.get(); + auto *ptr_var5 = GetSomeClass(), *ptr_var6 = my_struct.ptr.get(); + + // Test for the case where + // 1. The resulting type is the same as in the |ptr_var| and |complicated_var| + // examples + // 2. Deep in the initialization expression there is a member dereference + // of |ptr_field| + // but + // 3. The final/top-level initialization expression doesn't dereference + // |ptr_field|. + // No rewrite expected. + auto* not_affected_field_var = ConvertSomeClassToSomeClass(my_struct.ptr); + + // Test for pointer |auto| assigned from non-CheckedPtr-elligible field. + // No rewrite expected. + auto* func_ptr_var = my_struct.func_ptr_field; + + // Test for non-pointer |auto| assigned from CheckedPtr-elligible field. + // No rewrite expected. + auto non_pointer_auto_var = my_struct.ptr; + + // Test for non-auto pointer. + // No rewrite expected. + SomeClass* non_auto_ptr_var = my_struct.ptr; +} + +} // namespace auto_tests + +namespace printf_tests { + int ConvertSomeClassToInt(SomeClass* some_class) { return 123; } @@ -35,3 +112,59 @@ // No rewrite expected. MyPrintf("%d", ConvertSomeClassToInt(s.ptr)); } + +} // namespace printf_tests + +namespace cast_tests { + +void foo() { + MyStruct my_struct; + + // To get |const_cast<...>(...)| to compile after the rewrite we + // need to rewrite the casted expression. + // Expected rewrite: const_cast<SomeClass*>(my_struct.const_ptr.get()); + SomeClass* v = const_cast<SomeClass*>(my_struct.const_ptr.get()); + // Expected rewrite: const_cast<const SomeClass*>(my_struct.ptr.get()); + const SomeClass* v2 = const_cast<const SomeClass*>(my_struct.ptr.get()); + + // To get |reinterpret_cast<uintptr_t>(...)| to compile after the rewrite we + // need to rewrite the casted expression. + // Expected rewrite: reinterpret_cast<uintptr_t>(my_struct.ptr.get()); + uintptr_t u = reinterpret_cast<uintptr_t>(my_struct.ptr.get()); + + // There is no need to append |.get()| inside static_cast - unlike the + // const_cast and reinterpret_cast examples above, static_cast will compile + // just fine. + DerivedClass* d = static_cast<DerivedClass*>(my_struct.ptr); + void* void_var = static_cast<void*>(my_struct.ptr); +} + +} // namespace cast_tests + +namespace ternary_operator_tests { + +void foo(int x) { + MyStruct my_struct; + SomeClass* other_ptr = nullptr; + + // To avoid the following error type: + // conditional expression is ambiguous; 'const CheckedPtr<SomeClass>' + // can be converted to 'SomeClass *' and vice versa + // we need to append |.get()| to |my_struct.ptr| below. + // + // Expected rewrite: ... my_struct.ptr.get() ... + SomeClass* v = (x > 123) ? my_struct.ptr.get() : other_ptr; + + // Rewrite in the other position. + // Expected rewrite: ... my_struct.ptr.get() ... + SomeClass* v2 = (x > 456) ? other_ptr : my_struct.ptr.get(); + + // No rewrite is needed for the first, conditional argument. + // No rewrite expected. + int v3 = my_struct.ptr ? 123 : 456; + + // Test for 1st and 2nd arg. Only 2nd arg should be rewritten. + SomeClass* v4 = my_struct.ptr ? my_struct.ptr.get() : other_ptr; +} + +} // namespace ternary_operator_tests
diff --git a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc index 0787d36e..871e4fd 100644 --- a/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc +++ b/tools/clang/rewrite_raw_ptr_fields/tests/affected-expr-original.cc
@@ -2,13 +2,90 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -class SomeClass; +#include <stdint.h> // for uintptr_t + +class SomeClass {}; +class DerivedClass : public SomeClass {}; struct MyStruct { SomeClass* ptr; SomeClass* ptr2; + const SomeClass* const_ptr; + int (*func_ptr_field)(); }; +namespace auto_tests { + +MyStruct* GetMyStruct() { + return nullptr; +} + +SomeClass* GetSomeClass() { + return nullptr; +} + +SomeClass* ConvertSomeClassToSomeClass(SomeClass* some_class) { + return some_class; +} + +void foo() { + MyStruct my_struct; + + // After the rewrite |my_struct.ptr_field| is no longer a pointer, + // so |auto*| won't work. We fix this up, by appending |.get()|. + // Expected rewrite: auto* ptr_var = my_struct.ptr.get(); + auto* ptr_var = my_struct.ptr; + + // Tests for other kinds of initialization. + // Expected rewrite: |.get()| should be appended in both cases below. + auto* init_test1(my_struct.ptr); + auto* init_test2{my_struct.ptr}; + + // Test for handling of the |const| qualifier. + // Expected rewrite: const auto* ptr_var = my_struct.ptr.get(); + const auto* const_ptr_var = my_struct.ptr; + + // More complicated initialization expression, but the |ptr_field| struct + // member dereference is still the top/last expression here. + // Expected rewrite: ...->ptr.get() + auto* complicated_var = GetMyStruct()->ptr; + + // The test below covers: + // 1. Two variables with single |auto|, + // 2. Tricky placement of |*| (next to the variable name). + // Expected rewrite: ...ptr.get()... (twice in the 2nd example). + auto *ptr_var1 = my_struct.ptr, *ptr_var2 = GetSomeClass(); + auto *ptr_var3 = my_struct.ptr, *ptr_var4 = my_struct.ptr; + auto *ptr_var5 = GetSomeClass(), *ptr_var6 = my_struct.ptr; + + // Test for the case where + // 1. The resulting type is the same as in the |ptr_var| and |complicated_var| + // examples + // 2. Deep in the initialization expression there is a member dereference + // of |ptr_field| + // but + // 3. The final/top-level initialization expression doesn't dereference + // |ptr_field|. + // No rewrite expected. + auto* not_affected_field_var = ConvertSomeClassToSomeClass(my_struct.ptr); + + // Test for pointer |auto| assigned from non-CheckedPtr-elligible field. + // No rewrite expected. + auto* func_ptr_var = my_struct.func_ptr_field; + + // Test for non-pointer |auto| assigned from CheckedPtr-elligible field. + // No rewrite expected. + auto non_pointer_auto_var = my_struct.ptr; + + // Test for non-auto pointer. + // No rewrite expected. + SomeClass* non_auto_ptr_var = my_struct.ptr; +} + +} // namespace auto_tests + +namespace printf_tests { + int ConvertSomeClassToInt(SomeClass* some_class) { return 123; } @@ -33,3 +110,59 @@ // No rewrite expected. MyPrintf("%d", ConvertSomeClassToInt(s.ptr)); } + +} // namespace printf_tests + +namespace cast_tests { + +void foo() { + MyStruct my_struct; + + // To get |const_cast<...>(...)| to compile after the rewrite we + // need to rewrite the casted expression. + // Expected rewrite: const_cast<SomeClass*>(my_struct.const_ptr.get()); + SomeClass* v = const_cast<SomeClass*>(my_struct.const_ptr); + // Expected rewrite: const_cast<const SomeClass*>(my_struct.ptr.get()); + const SomeClass* v2 = const_cast<const SomeClass*>(my_struct.ptr); + + // To get |reinterpret_cast<uintptr_t>(...)| to compile after the rewrite we + // need to rewrite the casted expression. + // Expected rewrite: reinterpret_cast<uintptr_t>(my_struct.ptr.get()); + uintptr_t u = reinterpret_cast<uintptr_t>(my_struct.ptr); + + // There is no need to append |.get()| inside static_cast - unlike the + // const_cast and reinterpret_cast examples above, static_cast will compile + // just fine. + DerivedClass* d = static_cast<DerivedClass*>(my_struct.ptr); + void* void_var = static_cast<void*>(my_struct.ptr); +} + +} // namespace cast_tests + +namespace ternary_operator_tests { + +void foo(int x) { + MyStruct my_struct; + SomeClass* other_ptr = nullptr; + + // To avoid the following error type: + // conditional expression is ambiguous; 'const CheckedPtr<SomeClass>' + // can be converted to 'SomeClass *' and vice versa + // we need to append |.get()| to |my_struct.ptr| below. + // + // Expected rewrite: ... my_struct.ptr.get() ... + SomeClass* v = (x > 123) ? my_struct.ptr : other_ptr; + + // Rewrite in the other position. + // Expected rewrite: ... my_struct.ptr.get() ... + SomeClass* v2 = (x > 456) ? other_ptr : my_struct.ptr; + + // No rewrite is needed for the first, conditional argument. + // No rewrite expected. + int v3 = my_struct.ptr ? 123 : 456; + + // Test for 1st and 2nd arg. Only 2nd arg should be rewritten. + SomeClass* v4 = my_struct.ptr ? my_struct.ptr : other_ptr; +} + +} // namespace ternary_operator_tests
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 7331a2a2..b69c0f07 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -126,6 +126,9 @@ "chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_resources.grd": { "structures": [1400], }, + "chrome/browser/resources/chromeos/network_ui/network_health_resources.grd": { + "includes": [1410], + }, "chrome/browser/resources/component_extension_resources.grd": { "includes": [1420], "structures": [1440],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 7c0329d9..cdf067a3 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -43784,6 +43784,7 @@ <int value="662" label="content-visibility"/> <int value="663" label="text-decoration-thickness"/> <int value="664" label="page-orientation"/> + <int value="665" label="animation-timeline"/> </enum> <enum name="MappedEditingCommands"> @@ -69948,6 +69949,13 @@ <int value="7007" label="HIDDEN_to_HIDDEN"/> </enum> +<enum name="VirtualKeyboardEmojiTriggerType"> + <int value="0" label="Base emoji from the emoji picker"/> + <int value="1" label="Variant emoji from the emoji picker"/> + <int value="2" label="Base emoji from the popup"/> + <int value="3" label="Variant emoji from the popup"/> +</enum> + <enum name="VirtualKeyboardErrorTypeHashes"> <int value="30998784" label="Generic Error"/> </enum>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b271f68..37d6258 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -319,6 +319,15 @@ </summary> </histogram> +<histogram name="Accessibility.CrosSelectToSpeak.BackgroundShading" + enum="BooleanEnabled" expires_after="2021-05-28"> + <owner>katie@chromium.org</owner> + <owner>chrome-a11y-core@google.com</owner> + <summary> + Whether Select-to-Speak had background shading enabled when activated. + </summary> +</histogram> + <histogram name="Accessibility.CrosSelectToSpeak.SpeechPitch" enum="CrosSelectToSpeakSpeechPitch" expires_after="2018-08-01"> <obsolete> @@ -3518,7 +3527,8 @@ </histogram> <histogram name="Android.Language.UiIsSystemLanguage" enum="BooleanMatched" - expires_after="2020-10-14"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>perrier@chromium.org</owner> <owner>megjablon@chromium.org</owner> <summary> @@ -3528,7 +3538,8 @@ </histogram> <histogram name="Android.Language.WrongLanguageAfterResume" enum="Boolean" - expires_after="2020-09-06"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>heamy@chromium.org</owner> <summary> @@ -3859,7 +3870,7 @@ </histogram> <histogram name="Android.NativeStartupBridge.LoadFullBrowser" - enum="BooleanRequested" expires_after="2020-06-01"> + enum="BooleanRequested" expires_after="2021-06-01"> <owner>mheikal@chromium.org</owner> <owner>hnakashima@chromium.org</owner> <owner>hanxi@chromium.org</owner> @@ -7411,7 +7422,7 @@ </histogram> <histogram name="Apps.CreateShortcutIcon.Linux.Result" - enum="WebAppCreateShortcutIconLinuxResult" expires_after="M85"> + enum="WebAppCreateShortcutIconLinuxResult" expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7420,7 +7431,7 @@ </histogram> <histogram name="Apps.CreateShortcuts.Linux.Result" - enum="WebAppCreateShortcutLinuxResult" expires_after="M85"> + enum="WebAppCreateShortcutLinuxResult" expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7429,7 +7440,7 @@ </histogram> <histogram name="Apps.CreateShortcuts.Mac.Result" - enum="WebAppCreateShortcutMacResult" expires_after="M85"> + enum="WebAppCreateShortcutMacResult" expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7451,7 +7462,7 @@ <histogram name="Apps.FileHandler.Registration.Linux.RecreateShortcut.Result" enum="FileHandlerRegistrationLinuxRecreateShortcutResult" - expires_after="M85"> + expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7461,7 +7472,7 @@ </histogram> <histogram name="Apps.FileHandler.Registration.Linux.Result" - enum="FileHandlerRegistrationLinuxResult" expires_after="M85"> + enum="FileHandlerRegistrationLinuxResult" expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7470,7 +7481,7 @@ </histogram> <histogram name="Apps.FileHandler.Registration.Mac.Result" - enum="FileHandlerRegistrationMacResult" expires_after="M85"> + enum="FileHandlerRegistrationMacResult" expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7479,7 +7490,7 @@ </histogram> <histogram name="Apps.FileHandler.Registration.Win.Result" - enum="FileHandlerRegistrationWinResult" expires_after="M85"> + enum="FileHandlerRegistrationWinResult" expires_after="M90"> <owner>phillis@chromium.org</owner> <owner>cmumford@chromium.org</owner> <summary> @@ -7504,7 +7515,7 @@ </histogram> <histogram name="Apps.LockScreen.AppsProfile.Creation.Duration" units="ms" - expires_after="M85"> + expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7517,7 +7528,7 @@ </histogram> <histogram name="Apps.LockScreen.AppsProfile.Creation.Success" - units="BooleanSuccess" expires_after="M85"> + units="BooleanSuccess" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7529,7 +7540,7 @@ </histogram> <histogram name="Apps.LockScreen.DataItemStorage.ClearTextItemSize" - units="bytes" expires_after="M85"> + units="bytes" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7540,7 +7551,7 @@ </histogram> <histogram name="Apps.LockScreen.DataItemStorage.EncryptedItemSize" - units="bytes" expires_after="M85"> + units="bytes" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7551,7 +7562,7 @@ <histogram base="true" name="Apps.LockScreen.DataItemStorage.FailedOperationDuration" units="ms" - expires_after="M85"> + expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7561,7 +7572,7 @@ </histogram> <histogram base="true" name="Apps.LockScreen.DataItemStorage.OperationDuration" - units="ms" expires_after="M85"> + units="ms" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7571,7 +7582,7 @@ </histogram> <histogram base="true" name="Apps.LockScreen.DataItemStorage.OperationResult" - enum="LockScreenDataItemOperationResult" expires_after="M85"> + enum="LockScreenDataItemOperationResult" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7581,7 +7592,7 @@ </histogram> <histogram name="Apps.LockScreen.DataItemStorage.RegisteredItemsCount" - units="units" expires_after="M85"> + units="units" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7592,7 +7603,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.AppStatusOnNoteLaunch" - enum="LockScreenNoteAppStatusOnLaunch" expires_after="M85"> + enum="LockScreenNoteAppStatusOnLaunch" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7604,10 +7615,9 @@ </histogram> <histogram base="true" name="Apps.LockScreen.NoteTakingApp.AppWindowLifeTime" - units="ms" expires_after="M85"> + units="ms" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> - <owner>tbuckley@chromium.org</owner> <summary> The amount of time a lock screen enabled app window spent in a certain state during the app window activity. The state to which the histogram refers to @@ -7617,7 +7627,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.AvailabilityOnScreenLock" - enum="LockScreenActionAvailability" expires_after="M85"> + enum="LockScreenActionAvailability" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7627,7 +7637,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.FinalAppSessionState" - enum="LockScreenAppSessionState" expires_after="M85"> + enum="LockScreenAppSessionState" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7637,7 +7647,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.LaunchDurationAtLaunchCancel" - units="ms" expires_after="M85"> + units="ms" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7648,7 +7658,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.LaunchRequestOrdinalNumber" - units="units" expires_after="M85"> + units="units" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7660,7 +7670,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.LaunchRequestReason" - enum="NewLockScreenNoteRequestType" expires_after="M85"> + enum="NewLockScreenNoteRequestType" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7669,7 +7679,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.LockScreenAppUnloaded" - enum="LockScreenAppUnloadStatus" expires_after="M85"> + enum="LockScreenAppUnloadStatus" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7683,7 +7693,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.LockScreenInstallationDuration" - units="ms" expires_after="M85"> + units="ms" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7693,7 +7703,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.NoteTakingExitReason" - enum="LockScreenNoteTakingExitReason" expires_after="M85"> + enum="LockScreenNoteTakingExitReason" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7703,7 +7713,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.ReloadCountOnAppTermination" - units="units" expires_after="M85"> + units="units" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7715,7 +7725,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.TimeToLoadAppWindowContents" - units="ms" expires_after="M85"> + units="ms" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7726,7 +7736,7 @@ </histogram> <histogram name="Apps.LockScreen.NoteTakingApp.TimeToShowWindow" units="ms" - expires_after="M85"> + expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7761,7 +7771,7 @@ </histogram> <histogram name="Apps.NoteTakingApp.DefaultLaunchResult" - enum="NoteTakingAppLaunchResult" expires_after="M85"> + enum="NoteTakingAppLaunchResult" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -7771,7 +7781,7 @@ </histogram> <histogram name="Apps.NoteTakingApp.PreferredLaunchResult" - enum="NoteTakingAppLaunchResult" expires_after="M85"> + enum="NoteTakingAppLaunchResult" expires_after="2021-06-01"> <owner>dstockwell@chromium.org</owner> <owner>tbuckley@chromium.org</owner> <summary> @@ -18936,6 +18946,17 @@ </summary> </histogram> +<histogram name="Blink.Fonts.DataAccess.StreamCreation" enum="BooleanSuccess" + expires_after="M88"> + <owner>oyiptong@chromium.org</owner> + <owner>layout-dev@chromium.org</owner> + <owner>storage-dev@chromium.org</owner> + <summary> + Counts success or failure in attempting to obtain font bytes as stream with + base address from Skia. + </summary> +</histogram> + <histogram name="Blink.Fonts.Enumeration.Duration" units="ms" expires_after="M88"> <owner>oyiptong@chromium.org</owner> @@ -26862,14 +26883,13 @@ </histogram> <histogram name="Compositing.Browser.HitTestTimeToFindClosestLayer" - units="microseconds" expires_after="M85"> + units="microseconds" expires_after="2020-12-01"> <owner>yigu@chromium.org</owner> + <owner>animations-dev@chromium.org</owner> <summary> Time spent finding the closest matching layer to a given point whenever we do hit testing on LayerTreeImpl (in a browser process). - Team: animations-dev@chromium.org. - Warning: This metric may include reports from clients with low-resolution clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports will cause this metric to have an abnormal distribution. When considering @@ -27643,14 +27663,13 @@ </histogram> <histogram name="Compositing.Renderer.HitTestTimeToFindClosestLayer" - units="microseconds" expires_after="M85"> + units="microseconds" expires_after="2020-12-01"> <owner>yigu@chromium.org</owner> + <owner>animations-dev@chromium.org</owner> <summary> Time spent finding the closest matching layer to a given point whenever we do hit testing on LayerTreeImpl (in a renderer process). - Team: animations-dev@chromium.org. - Warning: This metric may include reports from clients with low-resolution clocks (i.e. on Windows, ref. |TimeTicks::IsHighResolution()|). Such reports will cause this metric to have an abnormal distribution. When considering @@ -41765,6 +41784,9 @@ <histogram name="DNS.StaleHostResolver.NetworkEarly" units="ms" expires_after="M85"> + <obsolete> + Removed 2020-06 + </obsolete> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -41776,6 +41798,9 @@ <histogram name="DNS.StaleHostResolver.NetworkLate" units="ms" expires_after="M85"> + <obsolete> + Removed 2020-06 + </obsolete> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -41787,6 +41812,9 @@ <histogram name="DNS.StaleHostResolver.RequestOutcome" enum="DNS.StaleHostResolverRequestOutcome" expires_after="M85"> + <obsolete> + Removed 2020-06 + </obsolete> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -41797,6 +41825,9 @@ <histogram name="DNS.StaleHostResolver.RestoreSizeOnCacheMiss" units="units" expires_after="M85"> + <obsolete> + Removed 2020-06 + </obsolete> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -41807,6 +41838,9 @@ <histogram name="DNS.StaleHostResolver.SizeOnCacheMiss" units="units" expires_after="M85"> + <obsolete> + Removed 2020-06 + </obsolete> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -41817,6 +41851,9 @@ <histogram name="DNS.StaleHostResolver.StaleAddressListDelta" enum="DNS.AddressListDeltaType" expires_after="M85"> + <obsolete> + Removed 2020-06 + </obsolete> <owner>pauljensen@chromium.org</owner> <owner>mef@chromium.org</owner> <summary> @@ -46563,6 +46600,26 @@ </summary> </histogram> +<histogram name="Enterprise.AppRestrictionLoadTime2.EmptyBundle" units="ms" + expires_after="2020-12-01"> + <owner>twellington@google.com</owner> + <owner>tedchcoc@chromium.org</owner> + <summary> + Records the time it takes to retrieve applicaton restrictions from the + system when the retrieved Bundle is empty. Android only. + </summary> +</histogram> + +<histogram name="Enterprise.AppRestrictionLoadTime2.NonEmptyBundle" units="ms" + expires_after="2020-12-01"> + <owner>twellington@google.com</owner> + <owner>tedchcoc@chromium.org</owner> + <summary> + Records the time it takes to retrieve applicaton restrictions from the + system when the retrieved Bundle is not empty. Android only. + </summary> +</histogram> + <histogram name="Enterprise.AppRestrictionsCacheLoad" enum="BooleanSuccess" expires_after="M85"> <obsolete> @@ -56350,7 +56407,7 @@ </histogram> <histogram name="Extensions.InstallPrompt.Type2" - enum="ExtensionInstallPromptType" expires_after="2020-06-01"> + enum="ExtensionInstallPromptType" expires_after="2021-06-01"> <owner>meacer@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner> <summary> @@ -68132,6 +68189,13 @@ <summary>How long the virtual keyboard was visible.</summary> </histogram> +<histogram name="InputMethod.VirtualKeyboard.Emoji.TriggerType" + enum="VirtualKeyboardEmojiTriggerType" expires_after="M89"> + <owner>shend@chromium.org</owner> + <owner>essential-inputs-team@google.com</owner> + <summary>How emojis were inserted.</summary> +</histogram> + <histogram name="InputMethod.VirtualKeyboard.ErrorType" enum="VirtualKeyboardErrorTypeHashes" expires_after="2020-02-01"> <owner>essential-inputs-team@google.com</owner> @@ -71544,7 +71608,8 @@ </histogram> <histogram name="LanguageSettings.Actions" enum="LanguageSettingsActionType" - expires_after="2020-08-17"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>googleo@chromium.org</owner> <summary> The actions taken on languages settings, recorded every time they happen. @@ -71553,20 +71618,23 @@ </histogram> <histogram name="LanguageSettings.PageImpression" - enum="LanguageSettingsPageType" expires_after="2020-11-08"> + enum="LanguageSettingsPageType" expires_after="2020-11-01"> + <owner>chrome-language@google.com</owner> <owner>googleo@chromium.org</owner> <summary>The type of panes which language settings loads.</summary> </histogram> <histogram name="LanguageUsage.AcceptLanguage" enum="LanguageCode" - expires_after="2020-10-14"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <owner>frechette@chromium.org</owner> <summary>Accept languages.</summary> </histogram> <histogram name="LanguageUsage.ApplicationLanguage" enum="LanguageCode" - expires_after="2020-10-14"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <owner>frechette@chromium.org</owner> <summary>Application languages used for UI.</summary> @@ -75505,6 +75573,43 @@ </summary> </histogram> +<histogram name="Media.Capabilities.DecodingInfo.Time.Video" units="ms" + expires_after="2021-01-15"> + <owner>chcunningham@chromium.org</owner> + <owner>mlamouri@google.com</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Time spent between receiving a decodingInfo() call and resolving it. It only + record successful calls and ignores audio-only. + </summary> +</histogram> + +<histogram name="Media.Capabilities.DecodingInfo.Time.Video.Clear" units="ms" + expires_after="2021-01-15"> + <owner>chcunningham@chromium.org</owner> + <owner>mlamouri@google.com</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Time spent between receiving a decodingInfo() call and resolving it. It only + record successful calls and ignores audio-only. This is a subset of + Media.Capabilities.DecodingInfo.RequestTime.Video that only takes into + account clear content. + </summary> +</histogram> + +<histogram name="Media.Capabilities.DecodingInfo.Time.Video.Encrypted" + units="ms" expires_after="2021-01-15"> + <owner>chcunningham@chromium.org</owner> + <owner>mlamouri@google.com</owner> + <owner>media-dev@chromium.org</owner> + <summary> + Time spent between receiving a decodingInfo() call and resolving it. It only + record successful calls and ignores audio-only. This is a subset of + Media.Capabilities.DecodingInfo.RequestTime.Video that only takes into + account encrypted content. + </summary> +</histogram> + <histogram name="Media.ChromeArcVideoDecodeAccelerator.InitializeResult" enum="ArcVideoDecodeAcceleratorResult" expires_after="2017-12-19"> <obsolete> @@ -78069,39 +78174,52 @@ </histogram> <histogram name="Media.Remoting.AllowedByPage" enum="BooleanEnabled" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Tracks whether a web page allows content to be remoted.</summary> </histogram> -<histogram name="Media.Remoting.AudioBitrate" units="kbps" expires_after="M77"> +<histogram name="Media.Remoting.AudioBitrate" units="kbps" + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary> Measured audio content transfer bitrate while remoting content. </summary> </histogram> <histogram name="Media.Remoting.AudioChannelLayout" enum="ChannelLayout" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Audio channel layout used while remoting content.</summary> </histogram> <histogram name="Media.Remoting.AudioCodec" enum="AudioCodec" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Audio codec used while remoting content.</summary> </histogram> <histogram name="Media.Remoting.AudioSamplesPerSecond" enum="AudioSampleRate" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Audio sampling rate while remoting audio content.</summary> </histogram> <histogram name="Media.Remoting.AudioSamplesPerSecondUnexpected" units="Hz" - expires_after="M85"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary> Audio sampling rate while remoting audio content (atypical values, in Hz). </summary> @@ -78156,7 +78274,7 @@ </histogram> <histogram name="Media.Remoting.SessionDuration" units="ms" - expires_after="2021-05-29"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> <owner>jophba@chromium.org</owner> <owner>openscreen-eng@google.com</owner> @@ -78164,22 +78282,28 @@ </histogram> <histogram name="Media.Remoting.SessionStartTrigger" - enum="RemotingStartTrigger" expires_after="M77"> + enum="RemotingStartTrigger" expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Tracks the trigger for starting a remoting session.</summary> </histogram> <histogram name="Media.Remoting.SessionStopTrigger" enum="RemotingStopTrigger" - expires_after="M77"> + expires_after="2021-07-01"> <!-- Name completed by histogram_suffixes name="RemotingSessionDuration" --> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Tracks the trigger for stopping a remoting session.</summary> </histogram> <histogram name="Media.Remoting.ShortSessionDuration" units="ms" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary> Measures the duration of each remoting session shorter than 15 seconds. </summary> @@ -78198,8 +78322,10 @@ </histogram> <histogram name="Media.Remoting.TimeUntilFirstPlayout" units="ms" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary> Measures how long, from the start of a remoting session, until content began playing out on the remote device. @@ -78207,8 +78333,10 @@ </histogram> <histogram name="Media.Remoting.TimeUntilRemoteInitialized" units="ms" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary> Measures how long, from the start of a remoting session, until a message was received from the remote device indicating initialization succeeded. @@ -78216,8 +78344,10 @@ </histogram> <histogram name="Media.Remoting.TrackConfiguration" - enum="RemotingTrackConfiguration" expires_after="M77"> + enum="RemotingTrackConfiguration" expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Tracks whether audio or video or both are remoted.</summary> </histogram> @@ -78232,33 +78362,45 @@ </summary> </histogram> -<histogram name="Media.Remoting.VideoAspectRatio" units="%" expires_after="M77"> +<histogram name="Media.Remoting.VideoAspectRatio" units="%" + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Aspect ratio of video while remoting content.</summary> </histogram> -<histogram name="Media.Remoting.VideoBitrate" units="kbps" expires_after="M77"> +<histogram name="Media.Remoting.VideoBitrate" units="kbps" + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary> Measured video content transfer bitrate while remoting content. </summary> </histogram> <histogram name="Media.Remoting.VideoCodec" enum="VideoCodec" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Video codec used while remoting content.</summary> </histogram> <histogram name="Media.Remoting.VideoCodecProfile" enum="VideoCodecProfile" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Video codec profile used while remoting content.</summary> </histogram> <histogram name="Media.Remoting.VideoNaturalWidth" units="pixels" - expires_after="M77"> + expires_after="2021-07-01"> <owner>miu@chromium.org</owner> + <owner>jophba@chromium.org</owner> + <owner>openscreen-eng@google.com</owner> <summary>Video width while remoting content.</summary> </histogram> @@ -116958,6 +117100,42 @@ </histogram> <histogram + name="PageLoad.Experimental.NavigationTiming.FinalLoaderCallbackToNavigationCommitSent" + units="ms" expires_after="2021-05-08"> + <owner>nhiroki@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The interval between when a callback for the navigation loader is last + invoked and when navigation commit message is sent to a renderer process for + the main resource of a main frame navigation. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.NavigationTiming.FinalRequestStartToFinalResponseStart" + units="ms" expires_after="2021-05-08"> + <owner>nhiroki@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The interval between when the final HTTP request is sent and when the + headers of the final HTTP response is received for the main resource of a + main frame navigation. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.NavigationTiming.FinalResponseStartToFinalLoaderCallback" + units="ms" expires_after="2021-05-08"> + <owner>nhiroki@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The interval between when the headers of the final HTTP response is received + and when a callback for the navigation loader is last invoked for the main + resource of a main frame navigation. + </summary> +</histogram> + +<histogram name="PageLoad.Experimental.NavigationTiming.FirstRequestStartToFirstResponseStart" units="ms" expires_after="2021-05-08"> <owner>nhiroki@chromium.org</owner> @@ -116976,8 +117154,41 @@ <owner>chrome-loading@google.com</owner> <summary> The interval between when the headers of the first HTTP response is received - for the main resource of a main frame navigation and when a callback for the - navigation loader is first invoked. + and when a callback for the navigation loader is first invoked for the main + resource of a main frame navigation. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.NavigationTiming.NavigationStartToFinalLoaderCallback" + units="ms" expires_after="2021-05-08"> + <owner>nhiroki@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time relative to navigation start that a callback for the navigation + loader is last invoked for the main resource of a main frame navigation. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.NavigationTiming.NavigationStartToFinalRequestStart" + units="ms" expires_after="2021-05-08"> + <owner>nhiroki@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time relative to navigation start that the final HTTP request is sent + for the main resource of a main frame navigation. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.NavigationTiming.NavigationStartToFinalResponseStart" + units="ms" expires_after="2021-05-08"> + <owner>nhiroki@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time relative to navigation start that the headers of the final HTTP + response is received for the main resource of a main frame navigation. </summary> </histogram> @@ -116999,8 +117210,7 @@ <owner>chrome-loading@google.com</owner> <summary> The time relative to navigation start that the first HTTP request is sent - for the main resource of a main frame navigation. See - page_load_metrics::PageLoadTiming::first_request_start for details. + for the main resource of a main frame navigation. </summary> </histogram> @@ -117011,8 +117221,7 @@ <owner>chrome-loading@google.com</owner> <summary> The time relative to navigation start that the headers of the first HTTP - response is received for the main resource of a main frame navigation. See - page_load_metrics::PageLoadTiming::first_response_start for details. + response is received for the main resource of a main frame navigation. </summary> </histogram> @@ -174360,6 +174569,7 @@ <histogram name="Translate.AcceptLanguages.CanBeAcceptDuration" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>googleo@chromium.org</owner> <summary> Time taken for the TranslateAcceptLanguages to decide if a given language is @@ -174368,7 +174578,8 @@ </histogram> <histogram name="Translate.AlwaysTranslateLang" units="units" - expires_after="2020-10-04"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the always translate option was selected in the @@ -174377,12 +174588,14 @@ </histogram> <histogram name="Translate.BubbleUiEvent" enum="TranslateBubbleUiEvent" - expires_after="2020-10-04"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>groby@google.com</owner> <summary>Tracks UI events related to the translate bubble.</summary> </histogram> <histogram name="Translate.CaptureText" units="ms" expires_after="M86"> + <owner>chrome-language@google.com</owner> <owner>dougarnett@google.com</owner> <owner>megjablon@google.com</owner> <summary> @@ -174415,9 +174628,9 @@ </histogram> <histogram name="Translate.CLD3.LanguageDetected" enum="CLD3LanguageCode" - expires_after="2020-11-22"> - <owner>frechette@chromium.org</owner> + expires_after="2020-12-01"> <owner>chrome-language@google.com</owner> + <owner>frechette@chromium.org</owner> <summary> Language of the input page detected by CLD3. This information is logged on every page load. @@ -174425,9 +174638,9 @@ </histogram> <histogram name="Translate.CLD3.LanguagePercentage" units="%" - expires_after="2020-11-01"> - <owner>frechette@chromium.org</owner> + expires_after="2020-12-01"> <owner>chrome-language@google.com</owner> + <owner>frechette@chromium.org</owner> <summary> Percentage of the bytes that are associated with the most popular language on the input page. Only recorded if the detection returned a @@ -174436,13 +174649,15 @@ </histogram> <histogram name="Translate.CompactInfobar.Event" enum="TranslateCompactUIEvent" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary>Various user actions performed in the translate infobar.</summary> </histogram> <histogram name="Translate.CompactInfobar.Language.AlwaysTranslate" - enum="CLD3LanguageCode" expires_after="2020-11-08"> + enum="CLD3LanguageCode" expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> Records the hashcode of the source language when always translate this @@ -174451,7 +174666,8 @@ </histogram> <histogram name="Translate.CompactInfobar.Language.MoreLanguages" - enum="CLD3LanguageCode" expires_after="2020-11-01"> + enum="CLD3LanguageCode" expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> Records the hashcode of the language clicked on the more languages menu. @@ -174459,7 +174675,8 @@ </histogram> <histogram name="Translate.CompactInfobar.Language.NeverTranslate" - enum="CLD3LanguageCode" expires_after="2020-10-04"> + enum="CLD3LanguageCode" expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> Records the hashcode of the source language when never translate this @@ -174468,7 +174685,8 @@ </histogram> <histogram name="Translate.CompactInfobar.Language.PageNotIn" - enum="CLD3LanguageCode" expires_after="2020-11-01"> + enum="CLD3LanguageCode" expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> Records the hashcode of the language clicked on the menu to indicate the @@ -174478,6 +174696,7 @@ <histogram name="Translate.CompactInfobar.Language.Translate" enum="CLD3LanguageCode" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> Records the hashcode of the language clicked on the infobar. @@ -174485,7 +174704,8 @@ </histogram> <histogram name="Translate.CompactInfobar.TranslationsPerPage" - units="translations" expires_after="2020-11-01"> + units="translations" expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> Records the number of times a page is translated, every time the page is @@ -174505,7 +174725,8 @@ </histogram> <histogram name="Translate.ContentLanguage" enum="TranslateLanguage" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> A page may provide a Content-Language HTTP header or a META tag. For each @@ -174514,7 +174735,8 @@ </histogram> <histogram name="Translate.DeclineTranslate" units="units" - expires_after="2020-10-04"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the "Nope" (don't translate) or the infobar's @@ -174523,7 +174745,8 @@ </histogram> <histogram name="Translate.DeclineTranslateCloseInfobar" units="units" - expires_after="2020-11-22"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the translate infobar was closed by clicking the X @@ -174532,7 +174755,8 @@ </histogram> <histogram name="Translate.DeclineTranslateDismissUI" units="units" - expires_after="2020-11-22"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the translate UI was closed without translating in the @@ -174546,6 +174770,7 @@ <histogram name="Translate.ExplicitLanguageAsk.Event" enum="TranslateExplicitAskPromptEventType" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@google.com</owner> <owner>anthonyvd@google.com</owner> <summary> @@ -174556,6 +174781,7 @@ <histogram name="Translate.ExplicitLanguageAsk.LanguageAdded" enum="CLD3LanguageCode" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@google.com</owner> <owner>anthonyvd@google.com</owner> <summary> @@ -174566,6 +174792,7 @@ <histogram name="Translate.ExplicitLanguageAsk.LanguageRemoved" enum="CLD3LanguageCode" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@google.com</owner> <owner>anthonyvd@google.com</owner> <summary> @@ -174575,11 +174802,11 @@ </histogram> <histogram name="Translate.ForceTriggerBackoffStateReached" enum="Boolean" - expires_after="2020-08-02"> + expires_after="2020-12-01"> <obsolete> Removed as of 04/2020. No longer used for analysis. </obsolete> - . + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <owner>yyushkina@chromium.org</owner> <summary> @@ -174590,8 +174817,8 @@ <histogram name="Translate.HrefHint.Status" enum="HrefTranslateStatus" expires_after="2020-12-01"> - <owner>megjablon@google.com</owner> <owner>chrome-language@google.com</owner> + <owner>megjablon@google.com</owner> <summary> For Google navigations, the hrefTranslate hint may trigger a translation automatically. If the hint is present on a Google navigation, record whether @@ -174603,7 +174830,8 @@ </histogram> <histogram name="Translate.HtmlLang" enum="TranslateLanguage" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> A page may provide a lang attribute in html tag. For each page load, @@ -174612,6 +174840,7 @@ </histogram> <histogram name="Translate.InfobarShown" enum="BooleanHit" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>anthonyvd@chromium.org</owner> <summary> The number of times the translate infobar was shown in the old translate UI @@ -174624,6 +174853,7 @@ <obsolete> Removed as of 11/2013, and replaced by Translate.InitiationStatus.v2. </obsolete> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The reason why Chrome decided to perform the next action (e.g., to show @@ -174633,7 +174863,8 @@ </histogram> <histogram name="Translate.InitiationStatus.v2" - enum="TranslateInitiationStatus" expires_after="2020-10-04"> + enum="TranslateInitiationStatus" expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The reason why Chrome decided to perform the next action (e.g., to show @@ -174643,10 +174874,10 @@ </histogram> <histogram name="Translate.LanguageDetection.ContentLength" units="characters" - expires_after="2021-04-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>dougarnett@chromium.org</owner> <owner>megjablon@chromium.org</owner> - <owner>chrome-language@google.com</owner> <summary> The number of characters of page content used for language detection. </summary> @@ -174675,6 +174906,7 @@ <histogram name="Translate.LanguageDetectionTiming" enum="TranslateLanguageDetectionTiming" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>andrewhayden@chromium.org</owner> <summary> For each page load, records whether language detection occurs on time or @@ -174685,9 +174917,9 @@ </histogram> <histogram name="Translate.LanguageSettingsIsShown" enum="BooleanShown" - expires_after="2020-10-18"> - <owner>frechette@chromium.org</owner> + expires_after="2020-12-01"> <owner>chrome-language@google.com</owner> + <owner>frechette@chromium.org</owner> <summary> Log everytime the language settings page is shown. This can be either user visits chrome://settings/languages or user visits the advanced languages @@ -174700,6 +174932,7 @@ <histogram name="Translate.LanguageVerification" enum="TranslateLanguageVerification" expires_after="M78"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@chromium.org</owner> <summary> For each page load, measures whether the provided HTML language (i.e. the @@ -174716,6 +174949,7 @@ <histogram name="Translate.LocalesOnDisabledByPrefs" enum="LanguageCode" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> Logs the user locale when the Translate feature is disabled by the user. @@ -174726,7 +174960,8 @@ </histogram> <histogram name="Translate.MobileMenuTranslate.Shown" enum="Boolean" - expires_after="2020-10-04"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@google.com</owner> <owner>frechette@chromium.org</owner> <summary> @@ -174736,7 +174971,8 @@ </histogram> <histogram name="Translate.ModifyOriginalLang" units="units" - expires_after="2020-08-30"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the original language in the translate infobar has been @@ -174745,7 +174981,8 @@ </histogram> <histogram name="Translate.ModifyTargetLang" units="units" - expires_after="2020-10-11"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the target language in the translate infobar has been @@ -174754,7 +174991,8 @@ </histogram> <histogram name="Translate.NeverTranslateLang" units="units" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the never translate option was selected in the translate @@ -174763,7 +175001,8 @@ </histogram> <histogram name="Translate.NeverTranslateSite" units="units" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the never translate site was selected in the translate @@ -174775,6 +175014,7 @@ <obsolete> Removed 2/2018 </obsolete> + <owner>chrome-language@google.com</owner> <owner>joelhockey@chromium.org</owner> <summary> The time spent capturing plain text from the DOM. This is reported by @@ -174784,12 +175024,14 @@ <histogram name="Translate.PageScheme" enum="TranslateScheme" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary>Counts translation target page schemes.</summary> </histogram> <histogram name="Translate.Ranker.Model.Status" enum="RankerModelStatus" - expires_after="2020-10-18"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Tracks the outcome of attempts to download a Translate Ranker Model. @@ -174798,6 +175040,7 @@ <histogram name="Translate.Ranker.Model.Version" units="date stamp" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> The date tamp (e.g., 20160916 -> 15 Sept 2016) which denotes the @@ -174807,6 +175050,7 @@ <histogram name="Translate.Ranker.QueryResult" enum="BooleanAccepted" expires_after="M85"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Whether the TranslateRanker accepts or denies to show the translation @@ -174816,6 +175060,7 @@ <histogram name="Translate.Ranker.Timer.CalculateScore" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Time taken for the TranslateRanker to use the translate ranker model to @@ -174825,6 +175070,7 @@ <histogram name="Translate.Ranker.Timer.DownloadModel" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Time taken for the Translate Ranker Model Loader to download its model from @@ -174834,6 +175080,7 @@ <histogram name="Translate.Ranker.Timer.ParseModel" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Time taken for the Translate Ranker Model Loader to parse its model, in ms. @@ -174842,6 +175089,7 @@ <histogram name="Translate.Ranker.Timer.ReadModel" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Time taken for the Translate Ranker Model Loader to read its model from @@ -174851,6 +175099,7 @@ <histogram name="Translate.Ranker.Timer.ShouldOfferTranslation" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Time taken for the TranslateRanker to decide if a given translation should @@ -174862,6 +175111,7 @@ <histogram name="Translate.Ranker.Timer.WriteModel" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>rogerm@google.com</owner> <summary> Time taken for the Translate Ranker Model Loader to write its model to local @@ -174870,7 +175120,8 @@ </histogram> <histogram name="Translate.ReportLanguageDetectionError" units="units" - expires_after="M85"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the "report this error" of options menu is @@ -174879,7 +175130,8 @@ </histogram> <histogram name="Translate.RevertTranslation" units="units" - expires_after="2020-11-22"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the show original button was clicked in the translate @@ -174892,6 +175144,7 @@ <obsolete> Removed 5/2013 by Translate.UndisplayableLanguage </obsolete> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the detected language is not supported by Translate @@ -174904,6 +175157,7 @@ <obsolete> Removed 7/2010. No longer tracked. </obsolete> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times an infobar proposing to translate a page has been shown. @@ -174911,7 +175165,8 @@ </histogram> <histogram name="Translate.ShowErrorInfobar" enum="TranslateError" - expires_after="M85"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> Chrome Translate shows an error infobar when an error happens on translation @@ -174921,7 +175176,8 @@ </histogram> <histogram name="Translate.ShowErrorUI" enum="TranslateError" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> Chrome Translate shows an error UI (infobar or bubble) when an error happens @@ -174932,6 +175188,7 @@ <histogram name="Translate.SimilarLanguageMatch" enum="BooleanMatched" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> This metrics is logged whenever a page is loaded. The logged value is @@ -174944,7 +175201,8 @@ </histogram> <histogram name="Translate.SourceLanguage" enum="CLD3LanguageCode" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@google.com</owner> <summary> The number of requests sent to the Translate server, grouped by source @@ -174953,7 +175211,8 @@ </histogram> <histogram name="Translate.TargetLanguage" enum="CLD3LanguageCode" - expires_after="2020-11-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>yyushkina@google.com</owner> <summary> The number of requests sent to the Translate server, grouped by target @@ -174962,9 +175221,9 @@ </histogram> <histogram name="Translate.TargetLanguage.Origin" - enum="TranslateTargetLanguageOrigin" expires_after="2020-11-01"> - <owner>megjablon@google.com</owner> + enum="TranslateTargetLanguageOrigin" expires_after="2020-12-01"> <owner>chrome-language@google.com</owner> + <owner>megjablon@google.com</owner> <summary> Where the target language was determined from. Can be the most recent target language, from the language model, the UI language, the user's accept @@ -174973,6 +175232,7 @@ </histogram> <histogram name="Translate.TimeToBeReady" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The time from injecting scripts for Chrome Translate to being ready to @@ -174981,6 +175241,7 @@ </histogram> <histogram name="Translate.TimeToLoad" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The time from injecting scripts for Chrome Translate to the finishing loads @@ -174989,12 +175250,14 @@ </histogram> <histogram name="Translate.TimeToTranslate" units="ms" expires_after="M77"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary>The time from starting translation to the completion.</summary> </histogram> <histogram name="Translate.Translate" enum="BooleanTranslate" - expires_after="2020-10-04"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The number of times the translate button was clicked in the translate @@ -175003,10 +175266,10 @@ </histogram> <histogram name="Translate.Translate.AMPCacheURL" enum="BooleanTranslate" - expires_after="2021-04-01"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>dougarnett@google.com</owner> <owner>megjablon@google.com</owner> - <owner>chrome-language@google.com</owner> <summary> The number of times the translate button was clicked in the translate infobar for a page that is likely an AMP Cache URL. @@ -175015,6 +175278,7 @@ <histogram name="Translate.TranslateFrameCount" units="frames" expires_after="M86"> + <owner>chrome-language@google.com</owner> <owner>dougarnett@google.com</owner> <owner>megjablon@google.com</owner> <summary> @@ -175024,7 +175288,7 @@ </histogram> <histogram name="Translate.TranslateSubframe.ErrorType" enum="TranslateError" - expires_after="2020-11-22"> + expires_after="2020-12-01"> <owner>dougarnett@google.com</owner> <owner>megjablon@google.com</owner> <summary> @@ -175035,7 +175299,8 @@ </histogram> <histogram name="Translate.TranslateSubframe.SuccessPercentage" units="%" - expires_after="2020-11-22"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>dougarnett@google.com</owner> <owner>megjablon@google.com</owner> <summary> @@ -175047,6 +175312,7 @@ <histogram name="Translate.UndisplayableLanguage" enum="LanguageCode" expires_after="M81"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> Logs an undisplayable language included in the language list sent by the @@ -175058,6 +175324,7 @@ <histogram name="Translate.UnsupportedLanguageAtInitiation" enum="LanguageCode" expires_after="M81"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> Logs an unsupported source language detected during initiation of the @@ -175069,7 +175336,8 @@ </histogram> <histogram name="Translate.UserActionDuration" units="ms" - expires_after="2020-11-29"> + expires_after="2020-12-01"> + <owner>chrome-language@google.com</owner> <owner>kenjibaheux@google.com</owner> <summary> The time from a page content language being determined to user requesting
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index cb73a9644a..e967f40 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -2,7 +2,7 @@ "trace_processor_shell": { "win": { "hash": "498eff8c51b4297bf08327846d68a6e782e5d5ff", - "remote_path": "perfetto_binaries/trace_processor_shell/win/84515482ba9ada62afb02d046ad621e91b898885/trace_processor_shell.exe" + "remote_path": "perfetto_binaries/trace_processor_shell/win/6049cc3934c0b0224aa6532cc36c8d16ce383e07/trace_processor_shell.exe" }, "mac": { "hash": "cdcb1f5b233c5d3472a561a8f567d4927dec850b", @@ -10,7 +10,7 @@ }, "linux": { "hash": "62e341128ce90ac37da1bcc7c391652c053bb159", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/84515482ba9ada62afb02d046ad621e91b898885/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/linux/6049cc3934c0b0224aa6532cc36c8d16ce383e07/trace_processor_shell" } } } \ No newline at end of file
diff --git a/tools/translation/helper/grd_helper.py b/tools/translation/helper/grd_helper.py index 5740e35..96b78f8 100644 --- a/tools/translation/helper/grd_helper.py +++ b/tools/translation/helper/grd_helper.py
@@ -34,7 +34,9 @@ def GetGrdMessages(grd_path_or_string, dir_path): - """Load the grd file and return a dict of message ids to messages.""" + """Load the grd file and return a dict of message ids to messages. + + Ignores non-translateable messages.""" doc = grit.grd_reader.Parse( grd_path_or_string, dir_path, @@ -46,6 +48,7 @@ return { msg.attrs['name']: msg for msg in doc.GetChildrenOfType(grit.node.message.MessageNode) + if msg.IsTranslateable() }
diff --git a/tools/translation/helper/grd_helper_unittest.py b/tools/translation/helper/grd_helper_unittest.py index 1aac247..69be763 100644 --- a/tools/translation/helper/grd_helper_unittest.py +++ b/tools/translation/helper/grd_helper_unittest.py
@@ -33,7 +33,7 @@ # listed here. self.assertTrue('IDS_TEST_STRING1' in messages) self.assertTrue('IDS_TEST_STRING2' in messages) - self.assertTrue('IDS_TEST_STRING_NON_TRANSLATEABLE' in messages) + self.assertFalse('IDS_TEST_STRING_NON_TRANSLATEABLE' in messages) def testReadGrdpMessages(self): messages = grd_helper.GetGrdpMessagesFromString(
diff --git a/ui/file_manager/file_manager/foreground/css/drive_welcome.css b/ui/file_manager/file_manager/foreground/css/drive_welcome.css index 63a70564..1a453bd 100644 --- a/ui/file_manager/file_manager/foreground/css/drive_welcome.css +++ b/ui/file_manager/file_manager/foreground/css/drive_welcome.css
@@ -45,17 +45,28 @@ box-sizing: border-box; flex: none; height: 72px; + opacity: 1; overflow-x: hidden; overflow-y: auto; position: relative; - transition: height 180ms ease, visibility 0ms linear 180ms; + transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1), + opacity 150ms ease 50ms; + visibility: visible; } -.dialog-container:not([drive-welcome='header']) .drive-welcome.header { +body:not(.files-ng) .dialog-container:not([drive-welcome='header']) +.drive-welcome.header { height: 0; visibility: hidden; } +body.files-ng .dialog-container:not([drive-welcome='header']) +.drive-welcome.header { + height: 0; + opacity: 0; + visibility: hidden; +} + body:not(.files-ng) .drive-welcome.header .drive-welcome-wrapper { color: white; display: flex;
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index f81c4f1..09c1b1e1 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1754,6 +1754,10 @@ flex: none; flex-direction: row; height: 40px; + opacity: 1; + transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1) 0s, + opacity 150ms ease 50ms; + visibility: visible; } body:not(.files-ng) .downloads-warning a:link, @@ -1798,6 +1802,13 @@ height: 0; } +body.files-ng .downloads-warning[hidden] { + display: flex !important; /* Overrides [hidden] for animation. */ + height: 0; + opacity: 0; + visibility: hidden; +} + @keyframes heightAnimation { 0% { display: flex; @@ -1829,15 +1840,27 @@ flex-direction: row; font-size: 13px; height: 40px; + opacity: 1; overflow: hidden; position: relative; + transition: height 300ms cubic-bezier(0.4, 0, 0.2, 1) 0s, + opacity 150ms ease 50ms; + visibility: visible; } -.volume-warning[hidden] { +body:not(.files-ng) .volume-warning[hidden] { border-top-width: 0; height: 0; } +body.files-ng .volume-warning[hidden] { + border-top-width: 0; + display: flex !important; /* Overrides [hidden] for animation. */ + height: 0; + opacity: 0; + visibility: hidden; +} + body:not(.files-ng) .volume-warning .drive-icon { background: white -webkit-image-set( url(../images/files/ui/drive_logo.png) 1x,
diff --git a/ui/gfx/x/xproto_types.cc b/ui/gfx/x/xproto_types.cc index 927a6aa..44bc624e 100644 --- a/ui/gfx/x/xproto_types.cc +++ b/ui/gfx/x/xproto_types.cc
@@ -58,6 +58,12 @@ sequence_ = base::nullopt; } +void FutureBase::SyncImpl(Error** raw_error) { + DCHECK(sequence_); + *raw_error = xcb_request_check(connection_->XcbConnection(), {*sequence_}); + sequence_ = base::nullopt; +} + void FutureBase::OnResponseImpl(ResponseCallback callback) { DCHECK(sequence_); connection_->AddRequest(*sequence_, std::move(callback));
diff --git a/ui/gfx/x/xproto_types.h b/ui/gfx/x/xproto_types.h index 1e00045..5e20529 100644 --- a/ui/gfx/x/xproto_types.h +++ b/ui/gfx/x/xproto_types.h
@@ -87,6 +87,7 @@ FutureBase& operator=(FutureBase&& future); void SyncImpl(Error** raw_error, uint8_t** raw_reply); + void SyncImpl(Error** raw_error); void OnResponseImpl(ResponseCallback callback); @@ -149,10 +150,7 @@ template <> inline Response<void> Future<void>::Sync() { Error* raw_error = nullptr; - uint8_t* raw_reply = nullptr; - SyncImpl(&raw_error, &raw_reply); - - DCHECK(!raw_reply); + SyncImpl(&raw_error); std::unique_ptr<Error, base::FreeDeleter> error; if (raw_error)
diff --git a/ui/gl/direct_composition_child_surface_win.cc b/ui/gl/direct_composition_child_surface_win.cc index 13b5de7..5a87fa9 100644 --- a/ui/gl/direct_composition_child_surface_win.cc +++ b/ui/gl/direct_composition_child_surface_win.cc
@@ -49,7 +49,9 @@ } // namespace -DirectCompositionChildSurfaceWin::DirectCompositionChildSurfaceWin() = default; +DirectCompositionChildSurfaceWin::DirectCompositionChildSurfaceWin( + bool use_angle_texture_offset) + : use_angle_texture_offset_(use_angle_texture_offset) {} DirectCompositionChildSurfaceWin::~DirectCompositionChildSurfaceWin() { Destroy(); @@ -343,8 +345,8 @@ } swap_rect_ = rectangle; + draw_offset_ = gfx::Vector2d(); - gfx::Vector2d draw_offset; if (dcomp_surface_) { TRACE_EVENT0("gpu", "DirectCompositionChildSurfaceWin::BeginDraw"); POINT update_offset; @@ -355,7 +357,7 @@ DLOG(ERROR) << "BeginDraw failed with error " << std::hex << hr; return false; } - draw_offset = gfx::Point(update_offset) - rectangle.origin(); + draw_offset_ = gfx::Point(update_offset) - rectangle.origin(); } else { TRACE_EVENT0("gpu", "DirectCompositionChildSurfaceWin::GetBuffer"); swap_chain_->GetBuffer(0, IID_PPV_ARGS(&draw_texture_)); @@ -364,25 +366,26 @@ g_current_surface = dcomp_surface_.Get(); - EGLint pbuffer_attribs[] = { - EGL_WIDTH, - size_.width(), - EGL_HEIGHT, - size_.height(), - EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, - EGL_TRUE, - EGL_TEXTURE_OFFSET_X_ANGLE, - draw_offset.x(), - EGL_TEXTURE_OFFSET_Y_ANGLE, - draw_offset.y(), - EGL_NONE, - }; + std::vector<EGLint> pbuffer_attribs; + pbuffer_attribs.push_back(EGL_WIDTH); + pbuffer_attribs.push_back(size_.width()); + pbuffer_attribs.push_back(EGL_HEIGHT); + pbuffer_attribs.push_back(size_.height()); + pbuffer_attribs.push_back(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE); + pbuffer_attribs.push_back(EGL_TRUE); + if (use_angle_texture_offset_) { + pbuffer_attribs.push_back(EGL_TEXTURE_OFFSET_X_ANGLE); + pbuffer_attribs.push_back(draw_offset_.x()); + pbuffer_attribs.push_back(EGL_TEXTURE_OFFSET_Y_ANGLE); + pbuffer_attribs.push_back(draw_offset_.y()); + } + pbuffer_attribs.push_back(EGL_NONE); EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(draw_texture_.Get()); - real_surface_ = - eglCreatePbufferFromClientBuffer(GetDisplay(), EGL_D3D_TEXTURE_ANGLE, - buffer, GetConfig(), pbuffer_attribs); + real_surface_ = eglCreatePbufferFromClientBuffer( + GetDisplay(), EGL_D3D_TEXTURE_ANGLE, buffer, GetConfig(), + pbuffer_attribs.data()); if (!real_surface_) { DLOG(ERROR) << "eglCreatePbufferFromClientBuffer failed with error " << ui::GetLastEGLErrorString(); @@ -404,6 +407,10 @@ dcomp_surface_ = std::move(surface); } +gfx::Vector2d DirectCompositionChildSurfaceWin::GetDrawOffset() const { + return use_angle_texture_offset_ ? gfx::Vector2d() : draw_offset_; +} + void DirectCompositionChildSurfaceWin::SetVSyncEnabled(bool enabled) { vsync_enabled_ = enabled; }
diff --git a/ui/gl/direct_composition_child_surface_win.h b/ui/gl/direct_composition_child_surface_win.h index 3a9c4ce..98a38f54 100644 --- a/ui/gl/direct_composition_child_surface_win.h +++ b/ui/gl/direct_composition_child_surface_win.h
@@ -17,7 +17,7 @@ class GL_EXPORT DirectCompositionChildSurfaceWin : public GLSurfaceEGL { public: - DirectCompositionChildSurfaceWin(); + explicit DirectCompositionChildSurfaceWin(bool use_angle_texture_offset); // GLSurfaceEGL implementation. bool Initialize(GLSurfaceFormat format) override; @@ -31,6 +31,7 @@ bool OnMakeCurrent(GLContext* context) override; bool SupportsDCLayers() const override; bool SetDrawRectangle(const gfx::Rect& rect) override; + gfx::Vector2d GetDrawOffset() const override; void SetVSyncEnabled(bool enabled) override; bool Resize(const gfx::Size& size, float scale_factor, @@ -61,6 +62,8 @@ // to it. Returns false if this fails. bool ReleaseDrawTexture(bool will_discard); + const bool use_angle_texture_offset_; + gfx::Size size_ = gfx::Size(1, 1); bool enable_dc_layers_ = false; bool has_alpha_ = true; @@ -76,6 +79,7 @@ EGLSurface real_surface_ = 0; bool first_swap_ = true; gfx::Rect swap_rect_; + gfx::Vector2d draw_offset_; // This is a number that increments once for every EndDraw on a surface, and // is used to determine when the contents have changed so Commit() needs to
diff --git a/ui/gl/direct_composition_surface_win.cc b/ui/gl/direct_composition_surface_win.cc index 3477f730..ef16dae 100644 --- a/ui/gl/direct_composition_surface_win.cc +++ b/ui/gl/direct_composition_surface_win.cc
@@ -286,7 +286,8 @@ : GLSurfaceEGL(), child_window_(parent_window), task_runner_(base::ThreadTaskRunnerHandle::Get()), - root_surface_(new DirectCompositionChildSurfaceWin()), + root_surface_(new DirectCompositionChildSurfaceWin( + settings.use_angle_texture_offset)), layer_tree_(std::make_unique<DCLayerTree>( settings.disable_nv12_dynamic_textures, settings.disable_larger_than_screen_overlays, @@ -741,6 +742,10 @@ return result; } +gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { + return root_surface_->GetDrawOffset(); +} + bool DirectCompositionSurfaceWin::SupportsGpuVSync() const { return base::FeatureList::IsEnabled(features::kDirectCompositionGpuVSync); }
diff --git a/ui/gl/direct_composition_surface_win.h b/ui/gl/direct_composition_surface_win.h index 4bab10a..82d17af 100644 --- a/ui/gl/direct_composition_surface_win.h +++ b/ui/gl/direct_composition_surface_win.h
@@ -38,6 +38,7 @@ bool disable_larger_than_screen_overlays = false; bool disable_vp_scaling = false; size_t max_pending_frames = 2; + bool use_angle_texture_offset = false; }; DirectCompositionSurfaceWin( @@ -121,6 +122,7 @@ bool SupportsDCLayers() const override; bool SupportsProtectedVideo() const override; bool SetDrawRectangle(const gfx::Rect& rect) override; + gfx::Vector2d GetDrawOffset() const override; bool SupportsGpuVSync() const override; void SetGpuVSyncEnabled(bool enabled) override; // This schedules an overlay plane to be displayed on the next SwapBuffers
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h index df670c3b..48e9dd3 100644 --- a/ui/gl/gl_context.h +++ b/ui/gl/gl_context.h
@@ -13,6 +13,7 @@ #include "base/cancelable_callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/synchronization/atomic_flag.h" #include "build/build_config.h" #include "ui/gfx/extension_set.h" @@ -90,7 +91,8 @@ }; // Encapsulates an OpenGL context, hiding platform specific management. -class GL_EXPORT GLContext : public base::RefCounted<GLContext> { +class GL_EXPORT GLContext : public base::RefCounted<GLContext>, + public base::SupportsWeakPtr<GLContext> { public: explicit GLContext(GLShareGroup* share_group);
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc index 3621c5d..2a5849f 100644 --- a/ui/gl/gl_image_memory.cc +++ b/ui/gl/gl_image_memory.cc
@@ -21,8 +21,10 @@ #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_enums.h" +#include "ui/gl/gl_surface.h" #include "ui/gl/gl_version_info.h" #include "ui/gl/scoped_binders.h" +#include "ui/gl/scoped_make_current.h" using gfx::BufferFormat; @@ -227,8 +229,11 @@ stride_(0) {} GLImageMemory::~GLImageMemory() { - if (buffer_) + if (buffer_ && original_context_ && original_surface_) { + ui::ScopedMakeCurrent make_current(original_context_.get(), + original_surface_.get()); glDeleteBuffersARB(1, &buffer_); + } } // static @@ -262,6 +267,7 @@ tex_image_from_pbo_is_slow = true; #endif // OS_WIN GLContext* context = GLContext::GetCurrent(); + DCHECK(context); if (!tex_image_from_pbo_is_slow && SupportsPBO(context) && (SupportsMapBuffer(context) || SupportsMapBufferRange(context))) { constexpr size_t kTaskBytes = 1024 * 1024; @@ -273,6 +279,10 @@ ScopedBufferBinder binder(GL_PIXEL_UNPACK_BUFFER, buffer_); glBufferData(GL_PIXEL_UNPACK_BUFFER, buffer_bytes_, nullptr, GL_DYNAMIC_DRAW); + original_context_ = context->AsWeakPtr(); + GLSurface* surface = GLSurface::GetCurrent(); + DCHECK(surface); + original_surface_ = surface->AsWeakPtr(); } } @@ -332,7 +342,9 @@ GLint data_row_length = DataRowLength(stride_, format_); base::Optional<std::vector<uint8_t>> gles2_data; - if (GLContext::GetCurrent()->GetVersionInfo()->is_es) { + GLContext* context = GLContext::GetCurrent(); + DCHECK(context); + if (context->GetVersionInfo()->is_es) { gles2_data = GLES2Data(size_, format_, stride_, memory_, &data_format, &data_type, &data_row_length); } @@ -350,17 +362,18 @@ size = buffer_bytes_; } - if (buffer_) { + bool uploaded = false; + if (buffer_ && original_context_.get() == context) { glTexImage2D(target, 0, GetInternalFormat(), size_.width(), size_.height(), 0, data_format, data_type, nullptr); ScopedBufferBinder binder(GL_PIXEL_UNPACK_BUFFER, buffer_); void* dst = nullptr; - if (SupportsMapBuffer(GLContext::GetCurrent())) { + if (SupportsMapBuffer(context)) { dst = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); } else { - DCHECK(SupportsMapBufferRange(GLContext::GetCurrent())); + DCHECK(SupportsMapBufferRange(context)); dst = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size, GL_MAP_WRITE_BIT); } @@ -381,13 +394,14 @@ glTexSubImage2D(target, 0, 0, 0, size_.width(), size_.height(), data_format, data_type, 0); + uploaded = true; } else { glDeleteBuffersARB(1, &buffer_); buffer_ = 0; } } - if (!buffer_) { + if (!uploaded) { glTexImage2D(target, 0, GetInternalFormat(), size_.width(), size_.height(), 0, data_format, data_type, src); }
diff --git a/ui/gl/gl_image_memory.h b/ui/gl/gl_image_memory.h index 2995a2b..ae30660 100644 --- a/ui/gl/gl_image_memory.h +++ b/ui/gl/gl_image_memory.h
@@ -10,11 +10,14 @@ #include <stddef.h> #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/numerics/safe_math.h" #include "ui/gfx/buffer_types.h" #include "ui/gl/gl_export.h" namespace gl { +class GLContext; +class GLSurface; class GL_EXPORT GLImageMemory : public GLImage { public: @@ -65,6 +68,9 @@ size_t stride_; unsigned buffer_ = 0; + // The context/surface from which the |buffer_| is created. + base::WeakPtr<GLContext> original_context_; + base::WeakPtr<GLSurface> original_surface_; size_t buffer_bytes_ = 0; int memcpy_tasks_ = 0;
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc index 0743f799..8284db4 100644 --- a/ui/gl/gl_surface.cc +++ b/ui/gl/gl_surface.cc
@@ -201,6 +201,10 @@ return false; } +gfx::Vector2d GLSurface::GetDrawOffset() const { + return gfx::Vector2d(); +} + void GLSurface::SetRelyOnImplicitSync() { // Some GLSurface derived classes might not implement this workaround while // still being allocated on devices where the workaround is enabled. @@ -465,6 +469,10 @@ return surface_->SetDrawRectangle(rect); } +gfx::Vector2d GLSurfaceAdapter::GetDrawOffset() const { + return surface_->GetDrawOffset(); +} + void GLSurfaceAdapter::SetRelyOnImplicitSync() { surface_->SetRelyOnImplicitSync(); }
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h index 660b1be..44ad295 100644 --- a/ui/gl/gl_surface.h +++ b/ui/gl/gl_surface.h
@@ -11,6 +11,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" @@ -44,7 +45,8 @@ // Encapsulates a surface that can be rendered to with GL, hiding platform // specific management. -class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { +class GL_EXPORT GLSurface : public base::RefCounted<GLSurface>, + public base::SupportsWeakPtr<GLSurface> { public: GLSurface(); @@ -269,6 +271,10 @@ // success. If failed, it is possible that the context is no longer current. virtual bool SetDrawRectangle(const gfx::Rect& rect); + // This is the amount by which the scissor and viewport rectangles should be + // offset. + virtual gfx::Vector2d GetDrawOffset() const; + // Tells the surface to rely on implicit sync when swapping buffers. virtual void SetRelyOnImplicitSync(); @@ -382,6 +388,7 @@ bool SupportsDCLayers() const override; bool SupportsProtectedVideo() const override; bool SetDrawRectangle(const gfx::Rect& rect) override; + gfx::Vector2d GetDrawOffset() const override; void SetRelyOnImplicitSync() override; void SetForceGlFlushOnSwapBuffers() override; bool SupportsSwapTimestamps() const override;
diff --git a/ui/gl/gl_surface_stub.cc b/ui/gl/gl_surface_stub.cc index cc6439e..59b750f 100644 --- a/ui/gl/gl_surface_stub.cc +++ b/ui/gl/gl_surface_stub.cc
@@ -54,6 +54,10 @@ return supports_draw_rectangle_; } +gfx::Vector2d GLSurfaceStub::GetDrawOffset() const { + return supports_draw_rectangle_ ? gfx::Vector2d(100, 200) : gfx::Vector2d(); +} + GLSurfaceStub::~GLSurfaceStub() {} } // namespace gl
diff --git a/ui/gl/gl_surface_stub.h b/ui/gl/gl_surface_stub.h index eee75d2..e87cf66 100644 --- a/ui/gl/gl_surface_stub.h +++ b/ui/gl/gl_surface_stub.h
@@ -33,6 +33,7 @@ bool BuffersFlipped() const override; GLSurfaceFormat GetFormat() override; bool SupportsDCLayers() const override; + gfx::Vector2d GetDrawOffset() const override; protected: ~GLSurfaceStub() override;
diff --git a/weblayer/browser/profile_impl.cc b/weblayer/browser/profile_impl.cc index 5178c71..ab25725 100644 --- a/weblayer/browser/profile_impl.cc +++ b/weblayer/browser/profile_impl.cc
@@ -83,8 +83,8 @@ ~DataClearer() override { remover_->RemoveObserver(this); } - void ClearData(int mask, base::Time from_time, base::Time to_time) { - int origin_types = + void ClearData(uint64_t mask, base::Time from_time, base::Time to_time) { + uint64_t origin_types = content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB; remover_->RemoveAndReply(from_time, to_time, mask, origin_types, this); @@ -166,7 +166,7 @@ // browser_context_ and then BrowsingDataRemover, which in turn would call // OnBrowsingDataRemoverDone(), even though the clearing hasn't been finished. - int remove_mask = 0; + uint64_t remove_mask = 0; // This follows what Chrome does: see browsing_data_bridge.cc. for (auto data_type : data_types) { switch (data_type) { @@ -288,7 +288,7 @@ profile->GetBrowserContext(), base::BindOnce(&ProfileImpl::NukeDataAfterRemovingData, std::move(profile), std::move(done_callback))); - int remove_all_mask = 0x8fffffff; + uint64_t remove_all_mask = 0xffffffffffffffffull; clearer->ClearData(remove_all_mask, base::Time::Min(), base::Time::Max()); }